river-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gtra...@apache.org
Subject svn commit: r1042831 - in /incubator/river/jtsk/skunk/surrogate: schemas/ src/org/apache/river/container/ src/org/apache/river/container/security/ test/org/apache/river/container/ test/org/apache/river/container/config/
Date Mon, 06 Dec 2010 22:46:43 GMT
Author: gtrasuk
Date: Mon Dec  6 22:46:42 2010
New Revision: 1042831

URL: http://svn.apache.org/viewvc?rev=1042831&view=rev
Log:
Work in progress.  Working on the container configuration subsystem.

Added:
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ConfigurationException.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Init.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Injected.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/LocalizedRuntimeException.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Strings.java
    incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/AnnotatedClassDeployerTest.java
Modified:
    incubator/river/jtsk/skunk/surrogate/schemas/config-sample.xml
    incubator/river/jtsk/skunk/surrogate/schemas/config.xsd
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/ASTNode.java
    incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/Strings.java
    incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/ConfigurationParserTest.java
    incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/config-test-doc.xml

Modified: incubator/river/jtsk/skunk/surrogate/schemas/config-sample.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/schemas/config-sample.xml?rev=1042831&r1=1042830&r2=1042831&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/schemas/config-sample.xml (original)
+++ incubator/river/jtsk/skunk/surrogate/schemas/config-sample.xml Mon Dec  6 22:46:42 2010
@@ -5,17 +5,37 @@
     Created on : November 24, 2010, 12:11 PM
     Author     : trasukg
     Description:
-        Purpose of the document follows.
+        This document is used to configure and bootstrap the container
+        components, establishing the core container's classpath and
+        instantiating the components that provide the container's
+        functionality.
+
+        The purpose of this file is to enable flexibility in configuring the
+        container for different purposes; it isn't generally something a
+        casual user would need to edit.
+
+        In particular, users would not be expected or encouraged to write
+        any new components to plug into the core container; there are no
+        guarantees made about future compatibility of the interfaces across
+        container releases.
 -->
 
 <cfg:container-config  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns:cfg='http://river.apache.org/xml/ns/container/config/1.0'
    xsi:schemaLocation='http://river.apache.org/xml/ns/container/config/1.0 file:/home/trasukg/development/surrogate/schemas/config.xsd'>
-    <cfg:default-policy></cfg:default-policy>
-    <cfg:discovery-context is-default="false" id="">
-        <cfg:locator>jini://localhost/</cfg:locator>
-        <cfg:group>TestGroup</cfg:group>
-    </cfg:discovery-context>
+   <!-- List jars and/or directories to be included in the container's
+   classloader.  Format is a space-separated list of jar files or directories.
+   The file specs can include wildcards.
+
+   Note that the core classloader will not have a usable codebase annotation
+   (the classpath will not be exported) so if components want to make
+   themselves remotely available, they will have to create another classloader.
+
+   -->
+
+   <cfg:classpath>
+      lib/*.jar
+   </cfg:classpath>
 
     <!-- List components here:
     Likely components would be:
@@ -42,4 +62,11 @@
     jar files shipped with the container?
 
     -->
+    <!-- The AnnotatedClassDeployer reads annotations on deployed classes and
+    implements the annotations (@Resource, @init, etc) on them.
+
+    It needs to be installed first so that other components are initialized
+    properly.
+    -->
+    <cfg:component class="org.apache.river.container.AnnotatedClassDeployer"/>
 </cfg:container-config>

Modified: incubator/river/jtsk/skunk/surrogate/schemas/config.xsd
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/schemas/config.xsd?rev=1042831&r1=1042830&r2=1042831&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/schemas/config.xsd (original)
+++ incubator/river/jtsk/skunk/surrogate/schemas/config.xsd Mon Dec  6 22:46:42 2010
@@ -7,11 +7,8 @@
     <xsd:element name="container-config">
         <xsd:complexType>
             <xsd:sequence>
-                <xsd:element name="default-policy" type="xsd:string"/>
+                <xsd:element ref="tns:classpath"/>
                 
-                <xsd:choice minOccurs="0" maxOccurs="unbounded">
-                    <xsd:element name="discovery-context" type="tns:DiscoveryContextType"/>
-                </xsd:choice>
             </xsd:sequence>
         </xsd:complexType>
     </xsd:element>
@@ -24,4 +21,6 @@
         <xsd:attribute name="is-default" type="xsd:boolean" default="false"/>
         <xsd:attribute name="id" type="xsd:string" use="optional"/>
     </xsd:complexType>
+    
+    <xsd:element name="classpath" type="xsd:string"/>
 </xsd:schema>

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
(added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/AnnotatedClassDeployer.java
Mon Dec  6 22:46:42 2010
@@ -0,0 +1,270 @@
+/*
+ * 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.river.container;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author trasukg
+ */
+public class AnnotatedClassDeployer implements ContextListener {
+
+    private static final Logger log =
+            Logger.getLogger(AnnotatedClassDeployer.class.getName(),
+            MessageNames.BUNDLE_NAME);
+    private Context context = null;
+    private List<DeployedObject> uninitializedObjects =
+            new ArrayList<DeployedObject>();
+    private Map<String, DeployedObject> initializedObjects =
+            new HashMap<String, DeployedObject>();
+
+    public void put(String name, Object o) {
+        /*
+        Scan the object's class and register any injection needs from it.
+         */
+        readInObject(name, o);
+        try {
+            /* Attempt to satisfy the object's injection needs from current
+            candidates.
+             */
+            resolve();
+        } catch (IllegalArgumentException ex) {
+            log.log(Level.SEVERE, null, ex);
+        } catch (IllegalAccessException ex) {
+            log.log(Level.SEVERE, null, ex);
+        } catch (InvocationTargetException ex) {
+            log.log(Level.SEVERE, null, ex);
+        }
+    }
+
+    public void remove(Object o) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public void setContext(Context ctx) {
+        this.context = ctx;
+    }
+
+    private void readInObject(String name, Object o) {
+        log.logp(Level.FINER, "AnnotatedClassDeployer", "readInObject",
+                MessageNames.READING_OBJECT,
+                new Object[]{name, o.getClass().getName()});
+
+        /* Get the object's class. */
+        Class cls = o.getClass();
+        DeployedObject deployed = new DeployedObject();
+        deployed.setDeployedObject(o);
+        deployed.setName(name);
+        List<Member> members = buildMemberList(cls);
+        List<Member> unresolved = deployed.getUnresolvedDependencies();
+        log.logp(Level.FINER, "AnnotatedClassDeployer", "readInObject",
+                MessageNames.READING_OBJECT_MEMBER_COUNT, members.size());
+
+        for (Member m : members) {
+            if (isAnnotatedAsInjected(m)) {
+                log.logp(Level.FINER, "AnnotatedClassDeployer", "readInObject",
+                        MessageNames.READING_OBJECT_ANNOTATED_MEMBER_FOUND, m.toString());
+                unresolved.add(m);
+            }
+            if (isInitMethod(m)) {
+                deployed.getInitMethods().add(m);
+            }
+        }
+        /* Add the object and list to our unsatisfied group. */
+        uninitializedObjects.add(deployed);
+    }
+
+    /**
+    It's an init method if it is
+    <ul>
+    <li>a Method</li>
+    <li>is annotated @Init</li>
+    <li>takes no parameter</li>
+    <li>returns void</li>
+    </ul>
+    @param m The method to evaluate.
+    @return
+     */
+    private boolean isInitMethod(Member m) {
+        AnnotatedElement annEm = (AnnotatedElement) m;
+        if (annEm.getAnnotation(Init.class) == null) {
+            return false;
+        }
+        if (m instanceof Field) {
+            /* Really can't happen since the annotation is marked as
+             method-only.
+             */
+            throw new ConfigurationException(MessageNames.FIELD_ANNOTATED_INIT,
+                    new Object[] {
+                        m.getDeclaringClass().getName(),
+                        m.getName()});
+
+        }
+        Method method=(Method) m;
+        if (method.getReturnType() != void.class) {
+            throw new ConfigurationException(MessageNames.INIT_METHOD_NOT_VOID,
+                    new Object[] {
+                        m.getDeclaringClass().getName(),
+                        m.getName(),
+                        method.getReturnType()});
+        }
+        if (method.getParameterTypes().length != 0) {
+            throw new ConfigurationException(MessageNames.INIT_METHOD_HAS_PARAMETERS,
+                    new Object[] {
+                        m.getDeclaringClass().getName(),
+                        m.getName()});
+        }
+        return true;
+    }
+
+    private boolean isAnnotatedAsInjected(Member m) {
+        AnnotatedElement annEm = (AnnotatedElement) m;
+        if (annEm.getAnnotation(Injected.class) != null) {
+            if (m instanceof Field) {
+                return true;
+            }
+            if (m instanceof Method && m.getName().startsWith(Strings.SET)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isNull(Object o, Member m) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException {
+        Object value = null;
+        if (m instanceof Field) {
+            value = ((Field) m).get(o);
+        }
+        if (m instanceof Method) {
+            value = ((Method) m).invoke(o, new Object[0]);
+        }
+        return value == null;
+    }
+
+    List<Member> buildMemberList(Class cls) throws SecurityException {
+        /* Construct a list of unsatisfied dependencies from the object.
+         */
+        List<Member> members = new ArrayList<Member>();
+        members.addAll(Arrays.asList(cls.getDeclaredMethods()));
+        members.addAll(Arrays.asList(cls.getDeclaredFields()));
+        return members;
+    }
+
+    private void resolve() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException
{
+        boolean changed = false;
+        do {
+            /* For each object in the unsatisfied group, */
+            /* Group of uninitialized objects may change while we're going
+            through them, so use a copy of the array.
+             */
+            for (DeployedObject deployed : new ArrayList<DeployedObject>(uninitializedObjects))
{
+                for (Member m : new ArrayList<Member>(deployed.getUnresolvedDependencies()))
{
+                    /* If there's a name annotated, lookup by name. */
+                    String name = nameAnnotation(m);
+                    Object val = null;
+                    if (!name.equals(Strings.EMPTY)) {
+                        val = initializedObjects.get(name);
+                    } else {
+                        val = findAssignable(m);
+                    }
+                    if (val != null) {
+                        inject(deployed, m, val);
+                    }
+                }
+                /* Attempt to resolve unsatisfied dependencies. */
+                /* If satisfied, remove from unsatisfied group and
+                put into candidate group, setting changed=true. */
+            }
+        } while (changed);
+
+    }
+
+    private String nameAnnotation(Member m) {
+        AnnotatedElement annEm = (AnnotatedElement) m;
+        Injected inj = (Injected) annEm.getAnnotation(Injected.class);
+        return inj.name();
+    }
+
+    /**
+    Find an injection candidate object that is assignable to the given member.
+    This candidate must be completely initialized.  As a special case, if the
+    type is assignable from the context object, then the context object will
+    be returned.
+    @param m
+    @return
+     */
+    private Object findAssignable(Member m) {
+        Class requiredType = null;
+        if (m instanceof Method) {
+            requiredType = ((Method) m).getParameterTypes()[0];
+        } else {
+            requiredType = ((Field) m).getType();
+        }
+
+        if (Context.class.isAssignableFrom(requiredType)) {
+            return context;
+        }
+        return null;
+    }
+
+    /** Inject a resolved value into the deployed object.
+    After the injection is complete, remove the member from our list of
+    unresolved dependencies for this object.  If there are no further
+    unresolved dependencies, call the object's init method and move it into
+    the initialized objects group.
+
+    @param deployed The holder for the deployment unit.
+    @param m The member (either Field or Method that is used to set the value.
+    @param val The value to set.
+     */
+    private void inject(DeployedObject deployed, Member m, Object val) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
+        log.logp(Level.FINER, "AnnotatedClassDeployer", "inject",
+                MessageNames.INJECT,
+                new Object[]{deployed.getName(), m.getName(), val});
+        memberSet(deployed.getDeployedObject(), m, val);
+        deployed.getUnresolvedDependencies().remove(m);
+        if (deployed.getUnresolvedDependencies().isEmpty()) {
+            // TODO: Invoke init method.
+            uninitializedObjects.remove(deployed);
+            initializedObjects.put(deployed.getName(), deployed);
+        }
+    }
+
+    private void memberSet(Object target, Member member, Object value) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
+        if (member instanceof Field) {
+            Field f = (Field) member;
+            f.set(target, value);
+        } else {
+            Method m = (Method) member;
+            m.invoke(target, value);
+        }
+    }
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ConfigurationException.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ConfigurationException.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ConfigurationException.java
(added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ConfigurationException.java
Mon Dec  6 22:46:42 2010
@@ -0,0 +1,30 @@
+/*
+ * 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.river.container;
+
+/**
+ * This exception indicates that an error was found in reading a configuration
+ file.
+ * @author trasukg
+ */
+public class ConfigurationException extends LocalizedRuntimeException {
+   public ConfigurationException(String messageKey, Object[] parameters) {
+       super(MessageNames.BUNDLE_NAME, messageKey, parameters);
+   }
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java (added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Context.java Mon Dec
 6 22:46:42 2010
@@ -0,0 +1,59 @@
+/*
+ * 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.river.container;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author trasukg
+ */
+public class Context {
+    ClassLoader rootClassLoader=null;
+    Map<String, Object> contents=new HashMap<String, Object>();
+    List<ContextListener> listeners=new ArrayList<ContextListener>();
+
+    /**
+     Put an object into the context.  Object will be indexed under its
+     fully qualified class name.
+     @param o
+     */
+    public void put(Object o) {
+        put(o.getClass().getName(), o);
+    }
+
+    public void put(String name, Object o) {
+        contents.put(name, o);
+        if (o instanceof ContextListener) {
+            ContextListener l=(ContextListener) o;
+            l.setContext(this);
+            listeners.add(l);
+        }
+        /*
+         If the added object happens to implement ContextListener, it
+         will be notified that it was added to the context.
+         */
+        for (ContextListener l: listeners) {
+            l.put(name, o);
+        }
+    }
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
(added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/ContextListener.java
Mon Dec  6 22:46:42 2010
@@ -0,0 +1,31 @@
+/*
+ * 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.river.container;
+
+/**
+ *
+ * @author trasukg
+ */
+public interface ContextListener {
+    public void put(String name, Object o);
+
+    public void remove(Object o);
+
+    public void setContext(Context ctx);
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
(added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/DeployedObject.java
Mon Dec  6 22:46:42 2010
@@ -0,0 +1,60 @@
+/*
+ * 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.river.container;
+
+import java.lang.reflect.Member;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ Holds information about an object that is being managed by the
+ AnnotatedClassDeployer.
+ * @author trasukg
+ */
+public class DeployedObject {
+    private Object deployedObject=null;
+    private String name;
+    private List<Member> unresolvedDependencies=new ArrayList<Member>();
+    private List<Member> initMethods=new ArrayList<Member>();
+
+    public List<Member> getInitMethods() {
+        return initMethods;
+    }
+
+    public Object getDeployedObject() {
+        return deployedObject;
+    }
+
+    public void setDeployedObject(Object deployedObject) {
+        this.deployedObject = deployedObject;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<Member> getUnresolvedDependencies() {
+        return unresolvedDependencies;
+    }
+
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Init.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Init.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Init.java (added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Init.java Mon Dec
 6 22:46:42 2010
@@ -0,0 +1,40 @@
+/*
+ * 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.river.container;
+
+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;
+
+/**
+ Identifies a method which should be called when all the @Injected
+ dependencies have been satisfied, to allow the target to initialize itself.
+ If the method throws any exception when called, the target will
+ not be available for
+ injection into any other object.
+ * @author trasukg
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Init {
+
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Injected.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Injected.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Injected.java (added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Injected.java Mon
Dec  6 22:46:42 2010
@@ -0,0 +1,61 @@
+/*
+ * 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.river.container;
+
+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;
+
+/**
+ <p>
+ Annotation to indicate that the contents of the annotated field should
+ be injected by the AnnotatedClassDeployer when the appropriate reference
+ becomes available.
+ </p>
+
+ <p>
+ By default, the injection is done by type; in other words the value is set
+ to the first thing in the context that is assignable to the target field.
+ If the annotation includes the 'name' attribute, then the injection is done
+ by name; the value is set to whatever is stored under that name in the context.
+ </p>
+
+ <p>
+ If the type of the target happens to be Context, then the context itself
+ will be injected.
+ </p>
+
+ <p>
+ An object in the context will not be injected into any other object until
+ it has been fully resolved and its initialization method has been called.
+ Nonetheless, the target object should not do anything with the injected
+ resource as part of the 'setter' method; it should initialize itself inside
+ a method flagged with the @Init annotation, which will be called when all the
+ @Injected fields/methods have been satisfied.
+ </p>
+ * @author trasukg
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface Injected {
+    String name() default Strings.EMPTY;
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/LocalizedRuntimeException.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/LocalizedRuntimeException.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/LocalizedRuntimeException.java
(added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/LocalizedRuntimeException.java
Mon Dec  6 22:46:42 2010
@@ -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.river.container;
+
+import java.text.MessageFormat;
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+/**
+ * This is a runtime exception with localized error messages.
+ * @author trasukg
+ */
+public class LocalizedRuntimeException extends RuntimeException {
+    private String messageBundleName;
+    private String messageKey;
+    private Object[] messageParameters;
+
+    /**
+     Construct a runtime exception with a localized message.
+     @param messageBundleName
+     @param messageKey
+     @param messageParameters
+     */
+    public LocalizedRuntimeException(String messageBundleName,
+            String messageKey,
+            Object[] messageParameters) {
+        this.messageBundleName=messageBundleName;
+        this.messageKey=messageKey;
+        this.messageParameters=messageParameters;
+    }
+
+    /**
+     Localize and return the error message, according to the default Locale.
+     Note that the resolution of the resource bundle and the localization is
+     deferred until this method is called, allowing the existence of different
+     resource bundles or locales in the thrower and receiver (e.g. in the case
+     of a serialized exception passed between two JVMs.
+
+     @return The localized message.
+     */
+    @Override
+    public String getMessage() {
+        ResourceBundle bundle=ResourceBundle.getBundle(messageBundleName);
+        String message=(String) bundle.getObject(messageKey);
+        return MessageFormat.format(message, messageParameters);
+    }
+
+    /**
+     Return the message localized using the given locale.
+     Note that the resolution of the resource bundle and the localization is
+     deferred until this method is called, allowing the existence of different
+     resource bundles or locales in the thrower and receiver (e.g. in the case
+     of a serialized exception passed between two JVMs.
+
+     @param locale
+     @return
+     */
+    public String getMessage(Locale locale) {
+        ResourceBundle bundle=ResourceBundle.getBundle(messageBundleName, locale);
+        String message=(String) bundle.getObject(messageKey);
+        return MessageFormat.format(message, messageParameters);
+    }
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
(added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/MessageNames.java
Mon Dec  6 22:46:42 2010
@@ -0,0 +1,37 @@
+/*
+ * 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.river.container;
+
+/**
+ * Constants that hold message names used in the message resource bundle.
+ * @author trasukg
+ */
+public class MessageNames {
+    public static final String BUNDLE_NAME="org.apache.river.container.Messages";
+
+    public static final String
+            FIELD_ANNOTATED_INIT="fieldAnnotatedInit",
+            INIT_METHOD_HAS_PARAMETERS="initMethodHasParameters",
+            INIT_METHOD_NOT_VOID="initMethodIsntVoid",
+            INJECT="inject",
+            READING_OBJECT="readingObject",
+            READING_OBJECT_MEMBER_COUNT="readingObject.memberCount",
+            READING_OBJECT_ANNOTATED_MEMBER_FOUND="readingObject.annotatedMemberFound",
+            READING_OBJECT_NON_ANNOTATED_MEMBER_FOUND="readingObject.nonAnnotatedMemberFound";
+}

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
(added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Messages.properties
Mon Dec  6 22:46:42 2010
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+fieldAnnotatedInit=File {1} on class {0} is incorrectly marked with the @Init \
+annotation.  Only methods of form ''void m()'' can be marked @Init.
+initMethodHasParameters=A method flagged as @Init must take no parameters.  \
+Method {1} on class {0} has parameters.
+initMethodIsntVoid=A method flagged as @Init must be void return type.  \
+Method {1} on class {0} returns {2}.
+inject=Injecting {2} into member ''{1}'' of deployed object {0}.
+readingObject=Reading instance of {1} named ''{0}'' for unresolved dependencies.
+readingObject.memberCount={0} members found.
+readingObject.annotatedMemberFound=Member ''{0}'' is annotated @Injected.
+readingObject.nonAnnotatedMemberFound=Member ''{0}'' is not annotated @Injected.

Added: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Strings.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Strings.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Strings.java (added)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/Strings.java Mon Dec
 6 22:46:42 2010
@@ -0,0 +1,30 @@
+/*
+ * 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.river.container;
+
+/**
+ *
+ * @author trasukg
+ */
+public class Strings {
+
+    public static final String
+        EMPTY = "",
+        SET = "set";
+}

Modified: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/ASTNode.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/ASTNode.java?rev=1042831&r1=1042830&r2=1042831&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/ASTNode.java
(original)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/ASTNode.java
Mon Dec  6 22:46:42 2010
@@ -1,7 +1,21 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ * 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.river.container.security;
 
 /**

Modified: incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/Strings.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/Strings.java?rev=1042831&r1=1042830&r2=1042831&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/Strings.java
(original)
+++ incubator/river/jtsk/skunk/surrogate/src/org/apache/river/container/security/Strings.java
Mon Dec  6 22:46:42 2010
@@ -1,6 +1,19 @@
 /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+ * 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.river.container.security;

Added: incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/AnnotatedClassDeployerTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/AnnotatedClassDeployerTest.java?rev=1042831&view=auto
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/AnnotatedClassDeployerTest.java
(added)
+++ incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/AnnotatedClassDeployerTest.java
Mon Dec  6 22:46:42 2010
@@ -0,0 +1,137 @@
+/*
+ * 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.river.container;
+
+import java.util.logging.Logger;
+import java.lang.reflect.Member;
+import java.util.List;
+import java.util.logging.Level;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ * Test Case for AnnotatedClassDeployer.
+ * @author trasukg
+ */
+public class AnnotatedClassDeployerTest {
+    Logger log=Logger.getLogger(AnnotatedClassDeployerTest.class.getName());
+
+    public AnnotatedClassDeployerTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        Logger.getLogger(AnnotatedClassDeployer.class.getName()).setLevel(Level.FINEST);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+    Context context = new Context();
+    AnnotatedClassDeployer UUT = new AnnotatedClassDeployer();
+
+    @Before
+    public void setUp() {
+        UUT.setContext(context);
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+    Test whether a single injected value is set on a component.
+     */
+    @Test
+    public void testReadsPrivateField() {
+        InjectionHarness harness = new InjectionHarness();
+        UUT.put(harness.getClass().getName(), harness);
+        List<Member> members = UUT.buildMemberList(harness.getClass());
+        assertTrue("No members found", members.size() > 0);
+    }
+
+    /**
+    Test whether a single injected value is set on a component.
+     */
+    @Test
+    public void testInjected() {
+        InjectionHarness harness = new InjectionHarness();
+        UUT.put(harness.getClass().getName(), harness);
+        assertEquals("Context wasn't injected", context, harness.context);
+    }
+
+    /**
+    Init method must be void return, and we should get an exception if it
+    specifies a return value;
+     */
+    @Test
+    public void testInitMethodWithNonVoidReturn() {
+        try {
+            Object harness = new InjectionHarnessWithNonVoidInit();
+            UUT.put(harness.getClass().getName(), harness);
+            fail("Should have got a ConfigurationException");
+        } catch (ConfigurationException cfe) {
+            log.log(Level.FINE, "ConfigurationException caught correctly", cfe);
+        }
+    }
+
+    /**
+    Test whether a single injected value is set on a component.
+     */
+    @Test
+    public void testInitCalled() {
+        InjectionHarness harness = new InjectionHarness();
+        UUT.put(harness.getClass().getName(), harness);
+        assertTrue("Init method wasn't called", harness.initialized);
+    }
+
+    /**
+    Test that if we have two items deployed, one will be injected into the
+    other.
+     */
+    @Test
+    public void testResourceInjected() {
+        fail("Implement me");
+    }
+
+    private class InjectionHarness {
+
+        @Injected
+        Context context = null;
+        boolean initialized = false;
+
+        @Init
+        void init() {
+            initialized = true;
+        }
+    }
+
+    private class InjectionHarnessWithNonVoidInit {
+
+        @Init
+        public int init() {
+            return -1;
+        }
+
+        ;
+    }
+}

Modified: incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/ConfigurationParserTest.java
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/ConfigurationParserTest.java?rev=1042831&r1=1042830&r2=1042831&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/ConfigurationParserTest.java
(original)
+++ incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/ConfigurationParserTest.java
Mon Dec  6 22:46:42 2010
@@ -46,6 +46,6 @@ public class ConfigurationParserTest {
         InputStream is=getClass().getResourceAsStream("config-test-doc.xml");
         ContainerConfig containerConfig=(ContainerConfig) um.unmarshal(is);
 
-        assertEquals("defPolicy", containerConfig.getDefaultPolicy());
+        assertEquals("lib/abc.jar", containerConfig.getClasspath());
     }
 }

Modified: incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/config-test-doc.xml
URL: http://svn.apache.org/viewvc/incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/config-test-doc.xml?rev=1042831&r1=1042830&r2=1042831&view=diff
==============================================================================
--- incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/config-test-doc.xml
(original)
+++ incubator/river/jtsk/skunk/surrogate/test/org/apache/river/container/config/config-test-doc.xml
Mon Dec  6 22:46:42 2010
@@ -11,7 +11,8 @@
 <cfg:container-config  xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns:cfg='http://river.apache.org/xml/ns/container/config/1.0'
    xsi:schemaLocation='http://river.apache.org/xml/ns/container/config/1.0 file:/home/trasukg/development/surrogate/schemas/config.xsd'>
-    <cfg:default-policy>defPolicy</cfg:default-policy>
+    <cfg:classpath>lib/abc.jar</cfg:classpath>
+
     <cfg:discovery-context is-default="false" id="">
         <cfg:locator></cfg:locator>
         <cfg:group></cfg:group>



Mime
View raw message