Return-Path: Delivered-To: apmail-sling-commits-archive@www.apache.org Received: (qmail 46884 invoked from network); 29 Sep 2009 12:25:27 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 29 Sep 2009 12:25:27 -0000 Received: (qmail 65951 invoked by uid 500); 29 Sep 2009 12:25:27 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 65895 invoked by uid 500); 29 Sep 2009 12:25:27 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 65886 invoked by uid 99); 29 Sep 2009 12:25:26 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 29 Sep 2009 12:25:26 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 29 Sep 2009 12:25:24 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id C317123888DB; Tue, 29 Sep 2009 12:25:04 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r819904 - in /sling/trunk/bundles/jcr/resource/src: main/java/org/apache/sling/jcr/resource/internal/ test/java/org/apache/sling/jcr/resource/internal/ Date: Tue, 29 Sep 2009 12:25:04 -0000 To: commits@sling.apache.org From: cziegeler@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20090929122504.C317123888DB@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: cziegeler Date: Tue Sep 29 12:25:04 2009 New Revision: 819904 URL: http://svn.apache.org/viewvc?rev=819904&view=rev Log: SLING-1126 : Support serializable objects - it's now possible to put serializable objects into the map, and retrieve them via get(String, Serializable.class) (or a sub class of Serializable) Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMap.java sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrPropertyMap.java sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMapTest.java sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrPropertyMapTest.java Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMap.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMap.java?rev=819904&r1=819903&r2=819904&view=diff ============================================================================== --- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMap.java (original) +++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMap.java Tue Sep 29 12:25:04 2009 @@ -65,14 +65,17 @@ */ public Object put(String key, Object value) { if ( key == null || key.indexOf('/') != -1 ) { - throw new IllegalArgumentException("Invalud key: " + key); + throw new IllegalArgumentException("Invalid key: " + key); + } + if ( value == null ) { + throw new NullPointerException("Value should not be null (key = " + key + ")"); } readFully(); final Object oldValue = this.get(key); try { - this.cache.put(key, new CacheEntry(value, getNode())); + this.cache.put(key, new CacheEntry(value, getNode().getSession())); } catch (RepositoryException re) { - throw new IllegalArgumentException("Value can't be put into node: " + value, re); + throw new IllegalArgumentException("Value for key " + key + " can't be put into node: " + value, re); } this.valueCache.put(key, value); if ( this.changedProperties == null ) { Modified: sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrPropertyMap.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrPropertyMap.java?rev=819904&r1=819903&r2=819904&view=diff ============================================================================== --- sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrPropertyMap.java (original) +++ sling/trunk/bundles/jcr/resource/src/main/java/org/apache/sling/jcr/resource/internal/JcrPropertyMap.java Tue Sep 29 12:25:04 2009 @@ -18,6 +18,12 @@ */ package org.apache.sling.jcr.resource.internal; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Calendar; @@ -33,6 +39,7 @@ import javax.jcr.PropertyIterator; import javax.jcr.PropertyType; import javax.jcr.RepositoryException; +import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.ValueFormatException; @@ -338,8 +345,14 @@ } @SuppressWarnings("unchecked") - private T convertToType(final CacheEntry entry, int index, Value jcrValue, - Class type) throws ValueFormatException, RepositoryException { + private T convertToType(final CacheEntry entry, + final int index, + final Value jcrValue, + final Class type) + throws ValueFormatException, RepositoryException { + if ( type.isInstance(entry.defaultValue) ) { + return (T) entry.defaultValue; + } if (String.class == type) { return (T) jcrValue.getString(); @@ -382,6 +395,29 @@ } else if (Property.class == type) { return (T) entry.property; + + } else if (Serializable.class.isAssignableFrom(type) + && jcrValue.getType() == PropertyType.BINARY) { + ObjectInputStream ois = null; + try { + ois = new ObjectInputStream(jcrValue.getStream(), null); + final Object obj = ois.readObject(); + if ( type.isInstance(obj) ) { + return (T)obj; + } + } catch (ClassNotFoundException cnfe) { + // ignore and use fallback + } catch (IOException ioe) { + // ignore and use fallback + } finally { + if ( ois != null ) { + try { + ois.close(); + } catch (IOException ignore) { + // ignore + } + } + } } // fallback in case of unsupported type @@ -408,6 +444,33 @@ public final Object defaultValue; + /** + * Create a value for the object. + * If the value type is supported directly through a jcr property type, + * the corresponding value is created. If the value is serializable, + * it is serialized through an object stream. Otherwise null is returned. + */ + private Value createValue(final Object obj, final Session session) + throws RepositoryException { + Value value = JcrResourceUtil.createValue(obj, session); + if ( value == null && obj instanceof Serializable ) { + try { + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(obj); + oos.close(); + final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + value = session.getValueFactory().createValue(bais); + } catch (IOException ioe) { + // we ignore this here and return null + } + } + return value; + } + + /** + * Create a new cache entry from a property. + */ public CacheEntry(final Property prop) throws RepositoryException { this.property = prop; @@ -421,7 +484,10 @@ this.defaultValue = JcrResourceUtil.toJavaObject(prop); } - public CacheEntry(final Object value, final Node node) + /** + * Create a new cache entry from a value. + */ + public CacheEntry(final Object value, final Session session) throws RepositoryException { this.property = null; this.defaultValue = value; @@ -430,12 +496,43 @@ final Object[] values = (Object[])value; this.values = new Value[values.length]; for(int i=0; i resolveClass(java.io.ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { + if ( this.classloader != null ) { + return Class.forName(classDesc.getName(), true, this.classloader); } + return super.resolveClass(classDesc); } } } Modified: sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMapTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMapTest.java?rev=819904&r1=819903&r2=819904&view=diff ============================================================================== --- sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMapTest.java (original) +++ sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrModifiablePropertyMapTest.java Tue Sep 29 12:25:04 2009 @@ -1,7 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ package org.apache.sling.jcr.resource.internal; import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.jcr.Node; @@ -93,6 +114,47 @@ assertContains(pvm2, initialSet()); } + public void testSerializable() + throws IOException { + final PersistableValueMap pvm = new JcrModifiablePropertyMap(this.rootNode); + assertContains(pvm, initialSet()); + assertNull(pvm.get("something")); + + // now put a serializable object + final List strings = new ArrayList(); + strings.add("a"); + strings.add("b"); + pvm.put("something", strings); + + // check if we get the list again + final List strings2 = (List) pvm.get("something"); + assertEquals(strings, strings2); + + pvm.save(); + + final PersistableValueMap pvm2 = new JcrModifiablePropertyMap(this.rootNode); + // check if we get the list again + final List strings3 = (List) pvm2.get("something", Serializable.class); + assertEquals(strings, strings3); + + } + + public void testExceptions() { + final PersistableValueMap pvm = new JcrModifiablePropertyMap(this.rootNode); + try { + pvm.put(null, "something"); + fail("Put with null key"); + } catch (IllegalArgumentException iae) {} + try { + pvm.put("something", null); + fail("Put with null value"); + } catch (NullPointerException iae) {} + try { + pvm.put("something", pvm); + fail("Put with non serializable"); + } catch (IllegalArgumentException iae) {} + } + protected JcrPropertyMap createPropertyMap(final Node node) { return new JcrModifiablePropertyMap(node); } Modified: sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrPropertyMapTest.java URL: http://svn.apache.org/viewvc/sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrPropertyMapTest.java?rev=819904&r1=819903&r2=819904&view=diff ============================================================================== --- sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrPropertyMapTest.java (original) +++ sling/trunk/bundles/jcr/resource/src/test/java/org/apache/sling/jcr/resource/internal/JcrPropertyMapTest.java Tue Sep 29 12:25:04 2009 @@ -1,4 +1,3 @@ -package org.apache.sling.jcr.resource.internal; /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -17,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +package org.apache.sling.jcr.resource.internal; + import java.util.Calendar; import java.util.Date; import java.util.Iterator;