Return-Path: X-Original-To: apmail-sling-commits-archive@www.apache.org Delivered-To: apmail-sling-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 54FE710705 for ; Fri, 26 Apr 2013 17:13:59 +0000 (UTC) Received: (qmail 68522 invoked by uid 500); 26 Apr 2013 17:13:59 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 68485 invoked by uid 500); 26 Apr 2013 17:13:59 -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 68474 invoked by uid 99); 26 Apr 2013 17:13:59 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 26 Apr 2013 17:13:59 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.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; Fri, 26 Apr 2013 17:13:48 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id DE5BE23888E7; Fri, 26 Apr 2013 17:13:23 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1476301 [1/2] - in /sling/whiteboard/dklco/sling-proxy: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/commons/ src/main/java/org/apache/sling/co... Date: Fri, 26 Apr 2013 17:13:21 -0000 To: commits@sling.apache.org From: dklco@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130426171323.DE5BE23888E7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: dklco Date: Fri Apr 26 17:13:19 2013 New Revision: 1476301 URL: http://svn.apache.org/r1476301 Log: Adding the current codebase for Sling Proxy Added: sling/whiteboard/dklco/sling-proxy/ (with props) sling/whiteboard/dklco/sling-proxy/README.md sling/whiteboard/dklco/sling-proxy/pom.xml sling/whiteboard/dklco/sling-proxy/src/ sling/whiteboard/dklco/sling-proxy/src/main/ sling/whiteboard/dklco/sling-proxy/src/main/java/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/AbstractProxyAdapterFactory.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxy.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxyService.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingChildren.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingProperty.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingReference.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/package.html sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DefaultSlingProxyServiceImpl.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DeferredIterator.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/ProxyBundleActivator.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/SlingInvocationHandler.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/GetMethodToStringImpl.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPEqualsImpl.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPHashCodeImpl.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPToStringImpl.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/MethodType.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/PrimeNumbers.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/package.html sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/package.html sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/Annotations.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/Classes.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/Methods.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/package.html sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/to/ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/to/BaseInvokedTO.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/to/InvokedChildrenTO.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/to/InvokedPropertyTO.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/to/InvokedTO.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/to/InvokedTOFactory.java sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/to/package.html sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/package.html sling/whiteboard/dklco/sling-proxy/src/site/ sling/whiteboard/dklco/sling-proxy/src/site/proxy.mdtext sling/whiteboard/dklco/sling-proxy/src/test/ sling/whiteboard/dklco/sling-proxy/src/test/java/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/BaseSlingProxyTest.java sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/TestSlingPropertyProxy.java sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/lang/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/lang/TestJDPEquals.java sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/lang/TestJDPHashCode.java sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/lang/TestJDPToString.java sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/samples/ sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/samples/DuplicateSlingPropertyProxy.java sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/samples/NoAnnotationSlingProxy.java sling/whiteboard/dklco/sling-proxy/src/test/java/org/apache/sling/commons/proxy/samples/SlingPropertyProxy.java sling/whiteboard/dklco/sling-proxy/src/test/resources/ sling/whiteboard/dklco/sling-proxy/src/test/resources/simplelogger.properties Propchange: sling/whiteboard/dklco/sling-proxy/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Fri Apr 26 17:13:19 2013 @@ -0,0 +1 @@ +target Added: sling/whiteboard/dklco/sling-proxy/README.md URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/README.md?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/README.md (added) +++ sling/whiteboard/dklco/sling-proxy/README.md Fri Apr 26 17:13:19 2013 @@ -0,0 +1,17 @@ +Apache Sling Proxy + +Java Dynamic Proxy implementation for Apache Sling. + +Getting Started +=============== + +This component uses a Maven 2 (http://maven.apache.org/) build +environment. It requires a Java 5 JDK (or higher) and Maven (http://maven.apache.org/) +2.0.7 or later. We recommend to use the latest Maven version. + +If you have Maven 2 installed, you can compile and +package the jar using the following command: + + mvn package + +See the Maven 2 documentation for other build features. Added: sling/whiteboard/dklco/sling-proxy/pom.xml URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/pom.xml?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/pom.xml (added) +++ sling/whiteboard/dklco/sling-proxy/pom.xml Fri Apr 26 17:13:19 2013 @@ -0,0 +1,112 @@ + + + + 4.0.0 + + org.apache.sling + sling + 13 + ../../../../parent/pom.xml + + + org.apache.sling.commons.proxy + bundle + 0.0.1-SNAPSHOT + + Apache Sling Proxy + Java Dynamic Proxy implementation for Apache Sling + + scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/proxy + scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/proxy + http://svn.apache.org/viewvc/sling/trunk/bundles/commons/proxy + + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + org.apache.sling.commons.proxy.impl.ProxyBundleActivator + + + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + org.apache.sling + org.apache.sling.api + 2.0.6 + + + org.apache.felix + org.apache.felix.scr.annotations + + + org.apache.sling + org.apache.sling.commons.classloader + 1.2.4 + + + org.slf4j + slf4j-api + + + org.osgi + org.osgi.compendium + + + org.osgi + org.osgi.core + + + commons-lang + commons-lang + 2.5 + provided + + + + junit + junit + test + + + org.slf4j + slf4j-simple + test + + + org.apache.sling + org.apache.sling.commons.testing + 2.0.12 + test + + + Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/AbstractProxyAdapterFactory.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/AbstractProxyAdapterFactory.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/AbstractProxyAdapterFactory.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/AbstractProxyAdapterFactory.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,70 @@ +/* + * 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.commons.proxy; + +import org.apache.felix.scr.annotations.Reference; +import org.apache.sling.api.adapter.AdapterFactory; +import org.apache.sling.api.resource.Resource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Abstract Adaptor Factory for adapting Sling Resources to Sling Dynamic + * Proxies. This adaptor utilizes Java Dynamic Proxies to allow adapting + * resources into objects which proxy calls against interface methods into the + * resource properties. + * + * Implementors of the SlingProxy interface should register an AdapterFactory + * Service with the services + * + * @see org.apache.sling.api.adapter.AdapterFactory + */ +public class AbstractProxyAdapterFactory implements AdapterFactory { + + /** + * The SLF4J Logger. + */ + private static final Logger log = LoggerFactory + .getLogger(AbstractProxyAdapterFactory.class); + + /** + * Reference to the Sling Proxy Service. + */ + @Reference + private SlingProxyService slingProxyService; + + /* + * (non-Javadoc) + * @see org.apache.sling.api.adapter.AdapterFactory#getAdapter(java.lang.Object, java.lang.Class) + */ + public AdapterType getAdapter(Object adaptable, + Class type) { + log.trace("getAdapter"); + + if (adaptable instanceof Resource) { + Resource resource = ((Resource) adaptable); + return slingProxyService.getProxy(resource, type); + } else { + log.warn("Unable to adapt object of type: {}", adaptable.getClass() + .getName()); + } + return null; + } + +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxy.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxy.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxy.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxy.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,35 @@ +/* + * 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.commons.proxy; + +import org.apache.sling.api.resource.Resource; + +/** + * An interface allowing developers to create interfaces who's method calls are + * proxies from the Sling repository. + */ +public interface SlingProxy { + + /** + * Retrieves the backing resource for this Sling Proxy. + * + * @return the resource backing the Sling Proxy + */ + Resource getBackingResource(); +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxyService.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxyService.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxyService.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/SlingProxyService.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,53 @@ +/* + * 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.commons.proxy; + +import org.apache.sling.api.resource.Resource; + +/** + * Service for retrieving ISlingProxy instances from Sling Resources. + */ +public interface SlingProxyService { + + /** + * Creates new ISlingProxy instances of the provided type type + * using the resource as the backing Sling Resource for the + * JavaBean accessor methods on type + * + * The following criteria must be met when invoking this method: + *
    + *
  1. resource must not be null
  2. + *
  3. type must not be null
  4. + *
  5. type must be an Interface
  6. + *
  7. Interface type must have at least one + * @SlingProperty, @SlingReference or @SlingChildren Annotation
  8. + *
+ * + * @param + * extends SlingProxy + * @param resource + * Resource - the backing Resource + * @param type + * Class - the interface that extends SlingProxy that is the + * Interface we are to create a new Proxy instance of + * @return the new proxy instance of type type + */ + AdapterType getProxy(Resource resource, + Class type); +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingChildren.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingChildren.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingChildren.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingChildren.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,79 @@ +/* + * 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.commons.proxy.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.apache.sling.api.resource.Resource; + +/** + * Annotation used to mark a Method as retrieving the children of a resource. + * The path is not required. If you do not specify a path the children of the + * proxied resource will be retrieved. Paths starting with '/' are absolute + * references, and do not have to be contained beneath the current Resource. + * Paths not starting with '/' are assumed to be relative to the current + * Resource. + * + * The child Resources at the path will be returned as an Iterator of either a + * resource or the type specified in the returnType property, according to the + * following rules (in order): + * + *
    + *
  1. If the return type is an instance of a Resource, the resource at the path + * will be returned
  2. + *
  3. If adapting the resource into the return class returns a non-null, this + * object will be returned
  4. + *
  5. If using the ProxyService to retrieve a proxy instance does not throw and + * error and does not return null, the resulting object will returned
  6. + *
  7. Otherwise, null will be returned
  8. + *
+ * + * Here are 3 examples, showing valid usages: + * + *
+ * @SlingChildren(path = "jcr:content")
+ * Iterator<Resource> getChildren();

+ * + * @SlingReference(returnType = ValueMap.class)
+ * Iterator<ValueMap> getSubnodeProperties();

+ * + * @SlingReference(path = "/content/page", returnType=IPageProxy.class)
+ * Iterator<IPageProxy> getSubPageProxes();

+ *
+ */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +@Documented +public @interface SlingChildren { + + /** + * The path of the child resources to retrieve. + */ + String path() default ""; + + /** + * The type to be returned as the generic type in the iterator. + */ + Class returnType() default Resource.class; + +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingProperty.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingProperty.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingProperty.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingProperty.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,146 @@ +/* + * 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.commons.proxy.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation used to mark a Method as being a JCR backed property. All JCR + * backed methods must use JavaBean style naming to identify them as either a + * 'getter' (getSomeValue, isSomevalue) or a JavaBean 'setter' 'setSomeValue'. + * + * 'name' and 'path' are both optional. If both are missing and/or empty, then + * the method name will be used to determine the corresponding JCR property + * name. In this case, namespaced property names are handled this way: + * + * @SlingProperty
+ * Date getCq_lastReplicated(); + * + * this will correspond to a JCR property name of: 'cq:lastReplicated' + * + * The ":" in the property name must be represented as a "_" underscore in the + * Property name. + * + * This style of property name identification will limit properties to being + * located immediately within the associated Resource Object. + * + * It is recommended to use 'name' and 'path' values as this enables the use of + * extravagant property names located anywhere within the JCR, not simply within + * the current Resource. + * + * Property names starting with '/' are absolute references, and do not have to + * be contained beneath the current Resource. Property names not starting with + * '/' are assumed to be relative to the current Resource. + * + * Here are 3 examples, one of each style: + * + *
+ * @SlingProperty(name = "cq:lastReplicated")
+ * Date getLastReplicated(); + *

+ * @SlingProperty(path = "par/image", name = "fileReference")
+ * String getImagePath(); + *

+ * @SlingProperty(path="/content/dam/geometrixx/documents/GeoCube_Datasheet.pdf/jcr:content/renditions/original/jcr:content", name="jcr:data")
+ * InputStream getGeoCubePDF();
+ *
+ */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +@Documented +public @interface SlingProperty { + + /** + * The default boolean, used to provide a default for booleans. + * + * @return the default boolean + */ + boolean defaultBoolean() default false; + + /** + * The default byte array, used to provide a default when the method returns + * an InputStream or a byte array. + * + * @return the default bytes + */ + byte[] defaultBytes() default {}; + + /** + * The default date, used to set the default value for Calendars, Dates & + * Long Timestamps. + * + * @return the default date + */ + long defaultDate() default -1; + + /** + * The default double, used to set the default values for doubles. + * + * @return the default double + */ + double defaultDouble() default 0.0; + + /** + * The default long, used to set the default values for long. + * + * @return the default long + */ + long defaultLong() default 0L; + + /** + * The default String, used to set the default String value. + * + * @return the default String + */ + String defaultString() default ""; + + /** + * The default String array, used to set the default String array value. + * + * @return the default String array + */ + String[] defaultStrings() default {}; + + /** + * The name of the property to retrieve from Sling. + * + * @return the name of the property to retrieve + */ + String name() default ""; + + /** + * The path to the property to retrieve, if it begins with '/' it will be + * treated as an absolute path, otherwise, it will be treated as a relative + * path. + * + * @return the path to the property to retrieve + */ + String path() default ""; + + /** + * Use a default value instead of just casting. + * + * @return the use default flag + */ + boolean useDefault() default false; +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingReference.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingReference.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingReference.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/SlingReference.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,73 @@ +/* + * 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.commons.proxy.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation used to mark a Method as referencing another resource. The path is + * required paths starting with '/' are absolute references, and do not have to + * be contained beneath the current Resource. Paths not starting with '/' are + * assumed to be relative to the current Resource. + * + * The Resource at the path will be returned depending on the return type of the + * method, according to the following rules (in order): + * + *
    + *
  1. If the return type is an instance of a Resource, the resource at the path + * will be returned
  2. + *
  3. If adapting the resource into the return class returns a non-null, this + * object will be returned
  4. + *
  5. If using the ProxyService to retrieve a proxy instance does not throw and + * error and does not return null, the resulting object will returned
  6. + *
  7. Otherwise, null will be returned
  8. + *
+ * + * Here are 3 examples, showing valid return types: + * + *
+ * @SlingReference(path = "/content/page")
+ * Resource getPage();

+ * + * @SlingReference(path = "/content/page")
+ * ValueMap getPageProperties();

+ * + * @SlingReference(path = "/content/page") + * IPageProxy getPageProxy(); + *
+ * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +@Documented +public @interface SlingReference { + + /** + * The path to the resource being referenced, if it begins with '/' it will + * be treated as an absolute path, otherwise, it will be treated as a + * relative path. + * + * @return the path to the resource being referenced + */ + String path(); +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/package.html URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/package.html?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/package.html (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/annotations/package.html Fri Apr 26 17:13:19 2013 @@ -0,0 +1,7 @@ + + + + + Provides the Annotations to configure SlingProxy interfaces. + + \ No newline at end of file Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DefaultSlingProxyServiceImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DefaultSlingProxyServiceImpl.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DefaultSlingProxyServiceImpl.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DefaultSlingProxyServiceImpl.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,91 @@ +/* + * 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.commons.proxy.impl; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.commons.proxy.SlingProxyService; +import org.apache.sling.commons.proxy.annotations.SlingChildren; +import org.apache.sling.commons.proxy.annotations.SlingProperty; +import org.apache.sling.commons.proxy.annotations.SlingReference; +import org.apache.sling.commons.proxy.impl.reflection.Annotations; + +/** + * Default implementation of the {@link org.apache.sling.commons.proxy.SlingProxyService} + */ +@Service(value = SlingProxyService.class) +@Component(description = "Creates ISlingProxy instances", immediate = true) +public final class DefaultSlingProxyServiceImpl implements SlingProxyService { + + /** + * Checks to see if an instance of the specified type can be + * instantiated from the resource. + * + * @param resource + * the resource to check + * @param type + * the type to check + */ + private void validateIsInstantiable(Resource resource, Class type) { + if (resource == null) { + String msg = "The backing Resource cannot be NULL."; + throw new NullPointerException(msg); + } + if (type == null) { + String msg = "The provided ISlingProxy Interface cannot be NULL."; + throw new NullPointerException(msg); + } + if (!type.isInterface()) { + String msg = "Proxy class " + type.getName() + + " must be an Interface."; + throw new UnsupportedOperationException(msg); + } + if (!Annotations.hasMethodAnnotation(type, SlingProperty.class) + && !Annotations.hasMethodAnnotation(type, SlingChildren.class) + && !Annotations.hasMethodAnnotation(type, SlingReference.class)) { + String msg = "Proxy interface " + + type.getName() + + " must have at least " + + "one Method with a @SlingProperty, @SlingReference or @SlingChildren annotation."; + throw new UnsupportedOperationException(msg); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.apache.sling.commons.proxy.SlingProxyService#getProxy(org.apache + * .sling.api.resource.Resource, java.lang.Class) + */ + public AdapterType getProxy(Resource resource, + Class type) { + validateIsInstantiable(resource, type); + + InvocationHandler ih = new SlingInvocationHandler(resource, this); + AdapterType rtn = type.cast(Proxy.newProxyInstance( + type.getClassLoader(), new Class[] { type }, ih)); + return rtn; + } + +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DeferredIterator.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DeferredIterator.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DeferredIterator.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/DeferredIterator.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,132 @@ +/* + * 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.commons.proxy.impl; + +import java.util.Iterator; + +import org.apache.sling.api.resource.Resource; +import org.apache.sling.commons.proxy.SlingProxyService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * An iterator which defers the loading of the elements from a backing of + * Iterator of resources. + * + * @param + * the object type for the interator contents, set in the + * SlingChildren annotation + */ +final class DeferredIterator implements Iterator { + + /** + * The SLF4j Logger + */ + private static final Logger log = LoggerFactory + .getLogger(DeferredIterator.class); + + /** + * The iterator of Resources which backs this deferred iterator + */ + private final Iterator backingResources; + + /** + * They type to be returned. + */ + private final Class returnType; + + /** + * A reference to the Sling Proxy service, used to load items which are + * SlingProxies + */ + private final SlingProxyService slingProxyService; + + /** + * Instantiates a Deferred Iterator. + * + * @param backingResources + * the Iterator of resources with which to back this iterator + * @param returnType + * the class which should be returned by next + * @param slingProxyService + * a reference to the Sling Proxy service + */ + public DeferredIterator(final Iterator backingResources, + final Class returnType, + final SlingProxyService slingProxyService) { + this.backingResources = backingResources; + this.returnType = returnType; + this.slingProxyService = slingProxyService; + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() { + return this.backingResources.hasNext(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#next() + */ + public E next() { + log.trace("next"); + final Resource resource = this.backingResources.next(); + + Object toReturn = null; + if (resource != null) { + if (Resource.class.equals(this.returnType)) { + log.debug("Returning resource as child"); + toReturn = resource; + } + + final Object adapted = resource.adaptTo(this.returnType); + if (adapted != null) { + log.debug("Returning adapted object as child"); + toReturn = adapted; + } + + try { + final Object proxy = this.slingProxyService.getProxy(resource, + this.returnType); + log.debug("Returning proxy as reference"); + toReturn = proxy; + } catch (final Exception e) { + log.warn("Exception getting proxy, null reference will be returned"); + } + } else { + log.debug("Referenced resource is null"); + } + return this.returnType.cast(toReturn); + } + + /* + * (non-Javadoc) + * + * @see java.util.Iterator#remove() + */ + public void remove() { + this.backingResources.remove(); + } + +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/ProxyBundleActivator.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/ProxyBundleActivator.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/ProxyBundleActivator.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/ProxyBundleActivator.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,68 @@ +/* + * 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.commons.proxy.impl; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Activator for the Sling Proxy bundle. + */ +public class ProxyBundleActivator implements BundleActivator { + private static final Logger log = LoggerFactory + .getLogger(ProxyBundleActivator.class); + private static BundleContext BUNDLE_CONTEXT; + + /** + * Get the bundle context. Will lock until the bundle context is returned. + * + * @return the bundle context + */ + public static BundleContext getBundleContext() { + return BUNDLE_CONTEXT; + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext bc) throws Exception { + log.info("start"); + BUNDLE_CONTEXT = bc; + log.debug("Bundle started successfully"); + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bc) throws Exception { + log.info("stop"); + BUNDLE_CONTEXT = null; + log.debug("Bundle stopped and context cleared"); + } + +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/SlingInvocationHandler.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/SlingInvocationHandler.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/SlingInvocationHandler.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/SlingInvocationHandler.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,326 @@ +/* + * 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.commons.proxy.impl; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceNotFoundException; +import org.apache.sling.api.resource.ValueMap; +import org.apache.sling.commons.proxy.SlingProxyService; +import org.apache.sling.commons.proxy.annotations.SlingChildren; +import org.apache.sling.commons.proxy.annotations.SlingReference; +import org.apache.sling.commons.proxy.impl.lang.GetMethodToStringImpl; +import org.apache.sling.commons.proxy.impl.lang.JDPEqualsImpl; +import org.apache.sling.commons.proxy.impl.lang.JDPHashCodeImpl; +import org.apache.sling.commons.proxy.impl.lang.MethodType; +import org.apache.sling.commons.proxy.impl.lang.PrimeNumbers; +import org.apache.sling.commons.proxy.impl.reflection.Annotations; +import org.apache.sling.commons.proxy.impl.to.BaseInvokedTO; +import org.apache.sling.commons.proxy.impl.to.InvokedChildrenTO; +import org.apache.sling.commons.proxy.impl.to.InvokedPropertyTO; +import org.apache.sling.commons.proxy.impl.to.InvokedTO; +import org.apache.sling.commons.proxy.impl.to.InvokedTOFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Invocation handler for proxies backed by a Sling Resource. + */ +public class SlingInvocationHandler implements InvocationHandler { + + /** + * SLF4J Logger + */ + private static final Logger log = LoggerFactory + .getLogger(SlingInvocationHandler.class); + + /** + * The backing Sling Resource + */ + private final Resource r; + + /** + * This caches all 'get' or 'is' method's return values. Calling 'set' will + * clear that properties cached value. + */ + private final Map cache; + + /** + * The SlingProxyService instance, used to retrieve references and children. + */ + private final SlingProxyService slingProxyService; + + /** + * Create a new ResourceInvocationHandler allowing invocation of all Methods + * that this InvocationHandler represents + * + * @param r + * Resource - the + * @param defaultSlingProxyServiceImpl + */ + SlingInvocationHandler(final Resource r, + final SlingProxyService slingProxyService) { + this.r = r; + this.slingProxyService = slingProxyService; + this.cache = new java.util.HashMap(); + } + + /** + * Get the path of the resource backing this invocation handler. + * + * @return the resource path + */ + public final String getResourcePath() { + return this.r.getPath(); + } + + /** + * Handle get children invocations. + * + * @param to + * the method invocation transfer object + * @return the returned object + */ + @SuppressWarnings("unchecked") + private Object handleGetChildren(final InvokedChildrenTO to) { + log.trace("handleGetChildren"); + + Resource resource = this.r; + if (!StringUtils.isEmpty(to.getPath())) { + log.debug("Loading child resources from: {}", to.getPath()); + if (to.isAbsolute()) { + resource = this.r.getResourceResolver().getResource( + to.getPath()); + } else { + resource = this.r.getResourceResolver().getResource(this.r, + to.getPath()); + } + } + + Class returnType = Resource.class; + if (to.getReturnType() != null) { + returnType = to.getReturnType(); + } + + Iterator toReturn = Collections.EMPTY_LIST.iterator(); + if (resource != null) { + toReturn = new DeferredIterator(resource + .getResourceResolver().listChildren(resource), + (Class) returnType, this.slingProxyService); + } + return toReturn; + } + + /** + * Handles get requests against a proxy to a Sling Resource. + * + * @param to + * the DTO for the invocation + * @return the result of the get access + * @throws Throwable + */ + private Object handleGetProperty(final InvokedPropertyTO to) + throws Throwable { + Object objReturn; + + // handle properties + if (this.cache.containsKey(to.getPropertyName())) { + objReturn = this.cache.get(to.getPropertyName()); + } else { + // TODO: refactor to also cache the ValueMap for a given path maybe? + ValueMap vm; + if (to.getPath() == null) { + vm = this.r.adaptTo(ValueMap.class); + } else { + Resource rsrc; + if (StringUtils.isEmpty(to.getPath())) { + rsrc = this.r; + } else if (to.isAbsolute()) { + rsrc = this.r.getResourceResolver().getResource( + to.getPath()); + } else { + rsrc = this.r.getResourceResolver().getResource(this.r, + to.getPath()); + } + if (rsrc == null) { + throw new ResourceNotFoundException( + "Unable to load resource at path: " + to.getPath()); + } + vm = rsrc.adaptTo(ValueMap.class); + } + + if (to.isUseDefault()) { + if (to.getMethod().getReturnType().equals(Boolean.class)) { + objReturn = vm.get(to.getName(), to.getDefaultBoolean()); + } else if (to.getMethod().getReturnType().equals(Byte[].class)) { + objReturn = vm.get(to.getName(), to.getDefaultBytes()); + } else if (to.getMethod().getReturnType() + .equals(InputStream.class)) { + final InputStream defaultIs = new ByteArrayInputStream( + to.getDefaultBytes()); + objReturn = vm.get(to.getName(), defaultIs); + } else if (to.getMethod().getReturnType() + .equals(Calendar.class)) { + final Calendar c = Calendar.getInstance(); + c.setTimeInMillis(to.getDefaultLong()); + objReturn = vm.get(to.getName(), c); + } else if (to.getMethod().getReturnType().equals(Date.class)) { + objReturn = vm.get(to.getName(), + new Date(to.getDefaultDate())); + } else if (to.getMethod().getReturnType().equals(Double.class)) { + objReturn = vm.get(to.getName(), to.getDefaultDouble()); + } else if (to.getMethod().getReturnType().equals(Long.class)) { + objReturn = vm.get(to.getName(), to.getDefaultLong()); + } else if (to.getMethod().getReturnType().equals(String.class)) { + objReturn = vm.get(to.getName(), to.getDefaultString()); + } else if (to.getMethod().getReturnType() + .equals(String[].class)) { + objReturn = vm.get(to.getName(), to.getDefaultStrings()); + } else { + log.warn( + "Unmappable return type {} specified and default requested", + to.getMethod().getReturnType()); + objReturn = vm.get(to.getName(), to.getMethod() + .getReturnType()); + } + } else { + objReturn = vm + .get(to.getName(), to.getMethod().getReturnType()); + } + this.cache.put(to.getPropertyName(), objReturn); + } + return objReturn; + } + + /** + * Handles a call to get a reference to another resource. + * + * @param to + * the method invocation transfer object + * @return the resulting object + */ + private Object handleGetReference(final BaseInvokedTO to) { + log.trace("handleGetReference"); + + Object value = null; + log.debug("Referencing resource at path: {}", to.getPath()); + Resource reference = null; + if (to.getPath().startsWith("/")) { + reference = this.r.getResourceResolver().getResource(to.getPath()); + } else { + reference = this.r.getResourceResolver().getResource(this.r, + to.getPath()); + } + log.debug("Loaded resource: {}", reference); + + if (reference != null) { + final Class returnType = to.getMethod().getReturnType(); + + log.debug("Attempting to get instance of {}", + returnType.getCanonicalName()); + if (Resource.class.equals(returnType)) { + log.debug("Returning resource as reference"); + value = reference; + } + + if (value == null) { + value = reference.adaptTo(returnType); + if (value != null) { + log.debug("Returning adapted object as reference"); + } + } + + if (value == null) { + try { + value = this.slingProxyService.getProxy(reference, + returnType); + if (value != null) { + log.debug("Returning adapted object as reference"); + } + } catch (final Exception e) { + log.warn("Exception getting proxy, null reference will be returned"); + } + } + } else { + log.debug("Referenced resource is null"); + } + log.debug("Returning value: {}", value); + + return value; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int hashCode = (SlingInvocationHandler.class.hashCode() * PrimeNumbers + .getInstance().get(2)) + this.r.getPath().hashCode(); + return hashCode; + } + + /* + * (non-Javadoc) @see + * java.lang.reflect.InvocationHandler#invoke(java.lang.Object, + * java.lang.reflect.Method, java.lang.Object[]) + */ + public Object invoke(final Object proxy, final Method method, + final Object[] args) throws Throwable { + + final InvokedTO to = InvokedTOFactory.newInstance(proxy, method, args); + if (to.isGetter()) { + if (Annotations.methodHasAnnotation(method, SlingReference.class)) { + return (this.handleGetReference((BaseInvokedTO) to)); + } else if (Annotations.methodHasAnnotation(method, + SlingChildren.class)) { + return (this.handleGetChildren((InvokedChildrenTO) to)); + } else { + return (this.handleGetProperty((InvokedPropertyTO) to)); + } + } else if (to.isType(MethodType.JavaBeanSet)) { + throw new UnsupportedOperationException( + "Setter methods not yet implemented."); + } else if (to.isType(MethodType.ToString)) { + return new GetMethodToStringImpl().toString(proxy); + } else if (to.isType(MethodType.HashCode)) { + return new JDPHashCodeImpl().hashCode(proxy); + } else if (to.isType(MethodType.Equals)) { + if ((args == null) || (args.length != 1)) { + final String msg = "Method 'equals' requires exactly 1 argument."; + throw new IllegalArgumentException(msg); + } + return new JDPEqualsImpl().equals(proxy, args[0]); + } else if (to.isType(MethodType.BackingResource)) { + return this.r; + } + throw new NoSuchMethodException("Method " + method.getName() + " DNE"); + } +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/GetMethodToStringImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/GetMethodToStringImpl.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/GetMethodToStringImpl.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/GetMethodToStringImpl.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,108 @@ +/* + * 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.commons.proxy.impl.lang; + +import java.lang.reflect.Method; +import java.util.List; + +import org.apache.sling.commons.proxy.impl.reflection.Methods; + +/** + * Generates a String representation based on the return values for all of the + * 'get' methods on the provided Object. + * + */ +public final class GetMethodToStringImpl { + + private final JDPToStringImpl tostring = new JDPToStringImpl(); + + /** + * Generates a String representation of an object. + * + * @param obj + * the object to generate a string of + * @return the string representation + */ + public String toString(Object obj) { + StringBuilder sb = new StringBuilder(); + + if (obj != null) { + addInterfaceInfo(obj, sb); + addMethodReturnValues(obj, Methods.getterMethods(obj), sb); + } else { + sb.append("null"); + } + + return sb.toString(); + } + + /** + * Adds the get method return values. + * + * @param obj + * the object upon which to invoke the getters + * @param list + * the list of methods + * @param sb + * the string builder to hold the string results + */ + private void addMethodReturnValues(Object obj, List list, + StringBuilder sb) { + sb.append("Get Method Values:"); + + if (list != null && list.size() > 0) { + for (Method m : list) { + sb.append("\n\t").append(m.getName()).append(" = "); + try { + Object rtnObj = m.invoke(obj, (Object[]) null); + sb.append("{").append(tostring.toString(rtnObj)) + .append("}"); + } catch (Exception ex) { + sb.append("caused ").append(ex.getClass().getName()) + .append(" - Message = ").append(ex.getMessage()); + } + } + } + + sb.append("\n\n"); + } + + /** + * Adding the interface information to the string representation. + * + * @param obj + * the object from which to cull the interfaces + * @param sb + * the string builder to hold the string representation + */ + private void addInterfaceInfo(Object obj, StringBuilder sb) { + Class[] cla = obj.getClass().getInterfaces(); + sb.append("Implements: ["); + + int max = (cla != null ? cla.length : -1); + for (int ndx = 0; ndx < max; ndx++) { + sb.append(cla[ndx].getName()); + if (ndx + 1 < max) { + sb.append(" , "); + } + } + + sb.append("]\n"); + } +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPEqualsImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPEqualsImpl.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPEqualsImpl.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPEqualsImpl.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,98 @@ +/* + * 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.commons.proxy.impl.lang; + +import java.lang.reflect.Proxy; + +import org.apache.sling.commons.proxy.impl.SlingInvocationHandler; +import org.apache.sling.commons.proxy.impl.reflection.Classes; + +/** + * Allows for testing the equality of the Sling Proxy instance. + */ +public class JDPEqualsImpl { + + /** + * Test if the Sling Proxy object is equal to another object. + * + * @param o1 + * the first object + * @param o2 + * the second object + * @return whether or not the objects are equal + */ + public boolean equals(Object o1, Object o2) { + if (o1 == o2) { + return true; + } + if (o1 == null || o2 == null) { + return false; + } + if (!areProxies(o1, o2)) { + return false; + } + + try { + SlingInvocationHandler rih1 = (SlingInvocationHandler) Proxy + .getInvocationHandler(o1); + SlingInvocationHandler rih2 = (SlingInvocationHandler) Proxy + .getInvocationHandler(o2); + if (Classes.haveSameInterfaces(o1, o2)) { + return stringEquals(rih1.getResourcePath(), + rih2.getResourcePath()); + } + } catch (ClassCastException ex) { + } + return false; + } + + /** + * Compares the two strings for equality, either string being null results + * in inequality. + * + * @param s1 + * the first string + * @param s2 + * the second string + * @return whether or not the two strings are equal + */ + private static boolean stringEquals(String s1, String s2) { + if (s1 == s2) { + return true; + } + if (s1 == null || s2 == null) { + return false; + } + return s1.equals(s2); + } + + /** + * Checks to see if the two objects are both JDP proxies. + * + * @param o1 + * the first object + * @param o2 + * the second object + * @return whether or not the objects are proxies + */ + private static boolean areProxies(Object o1, Object o2) { + return Proxy.isProxyClass(o1.getClass()) + && Proxy.isProxyClass(o2.getClass()); + } +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPHashCodeImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPHashCodeImpl.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPHashCodeImpl.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPHashCodeImpl.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,208 @@ +/* + * 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.commons.proxy.impl.lang; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import org.apache.sling.commons.proxy.impl.reflection.Classes; + +/** + * Generates a HashCode for the provided Object based on: If the Object is not a + * Proxy Object, the class name of the Object the implemented interfaces class + * name in ascending Order the Members hashCode value, evaluated in the members + * class name ascending order. If the value in NULL, a zero value is used. + * + * Any exceptions thrown while accessing the Objects member values will result + * in a IllegalStateException + */ +public final class JDPHashCodeImpl { + + /** + * Generates a hash code for the specified object. + * + * @param obj + * the object for which to generate the hash code + * @return the hash code for the object + * @throws IllegalStateException + */ + public int hashCode(Object obj) throws IllegalStateException { + List list = new java.util.ArrayList(); + + Class c = obj.getClass(); + + if (Proxy.isProxyClass(c)) { + list.add(Proxy.class.hashCode()); + handleInterfaces(c, list); + InvocationHandler ih = Proxy.getInvocationHandler(obj); + list.add(ih.hashCode()); + } else { + list.add(c.hashCode()); + handleInterfaces(c, list); + handleFields(obj, list); + } + + return calculate(list); + } + + /** + * Adds the has code for all of the interfaces in c into the + * list + * + * @param c + * the interfaces to handle + * @param list + * the list for containing the hash codes + */ + private void handleInterfaces(Class c, List list) { + Class[] ifcs = c.getInterfaces(); + if (ifcs != null) { + Arrays.sort(ifcs, new ClassNameComparator()); + for (Class ifc : ifcs) { + list.add(ifc.hashCode()); + } + } + } + + /** + * Adds the hash codes for all of the fields of obj into the + * list + * + * @param obj + * the object whose fields we should check + * @param list + * the list of hash codes + */ + private void handleFields(Object obj, List list) { + List fields = Classes.getFields(obj); + if (fields != null && fields.size() > 0) { + Collections.sort(fields, new FieldComparator()); + for (Field f : fields) { + try { + boolean unset = false; + if (!f.isAccessible()) { + unset = true; + f.setAccessible(true); + } + Object member = f.get(obj); + if (unset) { + f.setAccessible(false); + } + list.add((member == null ? 0 : member.hashCode())); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + } + } + + /** + * The first element in the List will always be the primary Class + * + * @param list + * @return + */ + private int calculate(List list) { + Iterator i = list.listIterator(); + + /** + * We start at PrimaryNumber index 2 because: 0 - is only a placeholder + * 1 - is the value 2 - which we never want to use + */ + int hash = i.next(), primeNdx = 2; + + PrimeNumbers pn = PrimeNumbers.getInstance(); + for (; i.hasNext();) { + hash = hash * pn.get(primeNdx) + i.next(); + } + + return hash; + } + + /** + * This will return NULL if both values are not null. Otherwise it will + * return: 0 - if both are NULL or both have the same Object identity -1 - + * if 'o1' is NULL but 'o2' is not 1 - if 'o1' is not null but 'o2' is + * + * @param o1 + * Object + * @param o2 + * Object + * @return see above + */ + private static final Integer compareForNull(Object o1, Object o2) { + if (o1 == o2) { + return 0; + } + if (o1 == null) { + return -1; + } + if (o2 == null) { + return 1; + } + return null; + } + + /** + * Compares two fields by name + */ + private static final class FieldComparator implements Comparator { + + /* + * (non-Javadoc) + * + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Field o1, Field o2) { + Integer rtn = compareForNull(o1, o2); + if (rtn != null) { + return rtn; + } + + return o1.getType().getName().compareTo(o2.getType().getName()); + } + } + + /** + * Compares classes by name. + */ + private static final class ClassNameComparator implements + Comparator> { + + /* + * (non-Javadoc) + * + * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) + */ + public int compare(Class o1, Class o2) { + Integer rtn = compareForNull(o1, o2); + if (rtn != null) { + return rtn; + } + + return o1.getName().compareTo(o2.getName()); + } + } +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPToStringImpl.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPToStringImpl.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPToStringImpl.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/JDPToStringImpl.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,101 @@ +/* + * 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.commons.proxy.impl.lang; + +import java.lang.reflect.Method; + +/** + * Generates a String representation of an object. + */ +public final class JDPToStringImpl { + + /** + * Generates a String representation of an object. + * + * @param obj + * the object to generate a string of + * @return the string representation + */ + public String toString(Object obj) { + StringBuilder sb = new StringBuilder(256); + + if (obj != null) { + if (!supportsToString(obj, sb)) { + handleByType(obj, sb); + } + } else { + sb.append("null"); + } + + return sb.toString(); + } + + /** + * Checks to see if the specified object contains a dedicated toString + * method. + * + * @param obj + * the object to check + * @param sb + * container for the results + * @return whether or not the object has a dedicated toString method + */ + private boolean supportsToString(Object obj, StringBuilder sb) { + try { + Method m = obj.getClass().getDeclaredMethod("toString", + (Class[]) null); + try { + Object result = m.invoke(obj, (Object[]) null); + sb.append(result); + } catch (Exception ex) { + sb.append("caused - ").append(ex.getClass().getName()) + .append(" - Message = ").append(ex.getMessage()); + } + return true; + } catch (SecurityException ex) { + } catch (NoSuchMethodException ex) { + } + + return false; + } + + /** + * Generates a toString based on the objects classes and methods. + * + * @param obj + * the object to generate the string for + * @param sb + * the string builder to write to + */ + private void handleByType(Object obj, StringBuilder sb) { + if (obj.getClass().isArray()) { + Object[] oa = (Object[]) obj; + sb.append("[ "); + for (int ndx = 0, max = oa.length; ndx < max; ndx++) { + sb.append(toString(oa[ndx])); + if (ndx + 1 < max) { + sb.append(" , "); + } + } + sb.append(" ]"); + } else { + sb.append(obj); + } + } +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/MethodType.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/MethodType.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/MethodType.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/MethodType.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,119 @@ +/* + * 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.commons.proxy.impl.lang; + +import java.lang.reflect.Method; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Types of Method's determined solely by the Method name. + */ +public enum MethodType { + + ToString("^(toString)$"), HashCode("^(hashCode)$"), Equals("^(equals)$"), BackingResource( + "^(getBackingResource)$"), JavaBeanGet("^get([A-Z])(\\w+)$"), JavaBeanIs( + "^is([A-Z])(\\w+)$"), JavaBeanSet("^is([A-Z])(\\w+)$"), Unknown( + "^$"); + + private final String regex; + + MethodType(String type) { + regex = type; + } + + /** + * Get the method pattern. + * + * @return the method pattern + */ + public Pattern getMethodPattern() { + return Pattern.compile(regex); + } + + /** + * Checks to see if the method matches the current type. + * + * @param m + * the method to check + * @return true if the method matches, false otherwise + */ + public boolean isType(Method m) { + return Pattern.matches(regex, m.getName()); + } + + /** + * Determine if the given MethodType enum is contained within the Array of + * MethodType's + * + * @param mta + * MethodType[] - the MethodType Array to search in + * @param mt + * MethodType - the MethodType to search for + * @return TRUE if 'mt' is found within 'mta' FALSE otherwise + */ + public static final boolean contains(MethodType[] mta, MethodType mt) { + for (MethodType _mt : mta) { + if (mt == _mt) + return true; + } + return false; + } + + /** + * Get the JavaBean name of the corresponding Method + * + * @param mt + * MethodType - The Method type of Method 'm' + * @param m + * Method + * @return String - If the method is of the given the JavaBean name for the + * provided Method, if it is of type 'mt' + */ + public static final String getBeanName(MethodType mt, Method m) { + Matcher match = mt.getMethodPattern().matcher(m.getName()); + String name = null; + if (match.find()) { + if (match.groupCount() == 1) { + name = match.group(1); + } else { + String pfx = match.group(1).toLowerCase(); + name = pfx + match.group(2); + } + } + return name; + } + + /** + * Checks the method against all of the default method types to determine + * which type the method is. + * + * @param m + * the method to check + * @return the type the method is + */ + public static final MethodType getMethodType(Method m) { + for (MethodType mt : values()) { + if (mt.isType(m)) { + return mt; + } + } + return Unknown; + } +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/PrimeNumbers.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/PrimeNumbers.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/PrimeNumbers.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/PrimeNumbers.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,77 @@ +/* + * 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.commons.proxy.impl.lang; + +/** + * The first 169 prime numbers + */ +public final class PrimeNumbers { + + private static final PrimeNumbers INSTANCE = new PrimeNumbers(); + private final int[] primes; + + /** + * Construct a new instance of the prime numbers + */ + private PrimeNumbers() { + // ** 14 per row + primes = new int[] { 0, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, + 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, + 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, + 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, + 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, + 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, + 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, + 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, + 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, + 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, + 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997 }; + } + + /** + * Get the PrimeNumbers instance. + * + * @return the prime numbers instance + */ + public static PrimeNumbers getInstance() { + return INSTANCE; + } + + /** + * Return 'n'th prime number. A 0 value for 'n' will return the first prime + * number. + * + * @param n + * int - the requested prime number. A value less than one will + * return the first prime number. + * + * @return int + */ + public int get(int n) { + n = (n < 1 ? 1 : n); + if (n >= primes.length) { + String msg = "We don't have a prime number for index " + n + "."; + throw new IndexOutOfBoundsException(msg); + } + return primes[n]; + } +} Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/package.html URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/package.html?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/package.html (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/lang/package.html Fri Apr 26 17:13:19 2013 @@ -0,0 +1,7 @@ + + + + + Provides helper classes for handling language default methods. + + \ No newline at end of file Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/package.html URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/package.html?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/package.html (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/package.html Fri Apr 26 17:13:19 2013 @@ -0,0 +1,7 @@ + + + + + Provides the implementation of the SlingProxy API. + + \ No newline at end of file Added: sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/Annotations.java URL: http://svn.apache.org/viewvc/sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/Annotations.java?rev=1476301&view=auto ============================================================================== --- sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/Annotations.java (added) +++ sling/whiteboard/dklco/sling-proxy/src/main/java/org/apache/sling/commons/proxy/impl/reflection/Annotations.java Fri Apr 26 17:13:19 2013 @@ -0,0 +1,92 @@ +/* + * 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.commons.proxy.impl.reflection; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +/** + * Methods for simplifying reflection annotation calls. + */ +public final class Annotations { + + /** + * For the given Class'clazz' determine if it has at least one method + * containing an Annotation of type or subclass of type 'annType'. + * + * @param + * - - Defines generic type T to be a + * subtype of Annotation + * @param clazz + * Class - the Class to get annotations from + * @param annType + * Class - the annotation types to get from Class 'clazz' + * @return TRUE if it does, FALSE otherwise + */ + public static boolean hasMethodAnnotation( + Class clazz, Class annType) { + Method[] ma = clazz.getMethods(); + if (ma == null) + return false; + + for (Method m : ma) { + Annotation[] ana = m.getAnnotations(); + if (ana == null) + continue; + + for (Annotation a : ana) { + if (annType.isAssignableFrom(a.getClass())) { + return true; + } + } + } + + return false; + } + + /** + * For the given Method 'method' determine if it has an Annotation of type + * or subclass of type 'annType'. + * + * @param + * - - Defines generic type T to be a + * subtype of Annotation + * @param method + * Method - the Method to get annotations from + * @param annType + * Class - the annotation types to get from Class 'clazz' + * @return TRUE if it does, FALSE otherwise + */ + public static boolean methodHasAnnotation( + Method method, Class annType) { + + Annotation[] ana = method.getAnnotations(); + if (ana == null) { + return false; + } + + for (Annotation a : ana) { + if (annType.isAssignableFrom(a.getClass())) { + return true; + } + } + + return false; + } +}