river-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gtra...@apache.org
Subject [07/40] git commit: Initial import of River Container project into git.
Date Mon, 13 Jan 2014 03:35:14 GMT
Initial import of River Container project into git.

River Container began as jtsk/skunk/RiverSurrogate.  This import does two things: It begins the process of implementing the appropriate poms and project structure to build with Apache Maven, and it moves the project to a git repository.

Future work is required to finish the Maven build.  We need to add modules to build the reggie module sar, and to build the test container.  Later we need to add the module to build the default user container.

Project: http://git-wip-us.apache.org/repos/asf/river-container/repo
Commit: http://git-wip-us.apache.org/repos/asf/river-container/commit/9ab01093
Tree: http://git-wip-us.apache.org/repos/asf/river-container/tree/9ab01093
Diff: http://git-wip-us.apache.org/repos/asf/river-container/diff/9ab01093

Branch: refs/heads/master
Commit: 9ab0109300201db750163e443f87e5630737a080
Parents: 
Author: Greg Trasuk <gtrasuk@apache.org>
Authored: Mon May 27 03:01:50 2013 -0400
Committer: Greg Trasuk <gtrasuk@apache.org>
Committed: Mon May 27 03:01:50 2013 -0400

----------------------------------------------------------------------
 pom.xml                                         |  12 +
 river-container-core/pom.xml                    |  81 +++
 .../river/container/AbstractConnector.java      |  48 ++
 .../river/container/AnnotatedClassDeployer.java | 518 +++++++++++++++++++
 .../apache/river/container/AttributeStore.java  |  43 ++
 .../river/container/AttributeStoreImpl.java     |  52 ++
 .../org/apache/river/container/Bootstrap.java   | 259 ++++++++++
 .../container/CommandLineArgumentParser.java    |  60 +++
 .../river/container/ConfigurationException.java |  34 ++
 .../org/apache/river/container/Context.java     |  84 +++
 .../apache/river/container/ContextListener.java |  56 ++
 .../apache/river/container/DeployedObject.java  |  76 +++
 .../river/container/DeploymentListener.java     |  28 +
 .../org/apache/river/container/FileUtility.java |  49 ++
 .../apache/river/container/FileUtilityImpl.java |  63 +++
 .../java/org/apache/river/container/Host.java   |  70 +++
 .../java/org/apache/river/container/Init.java   |  40 ++
 .../org/apache/river/container/Injected.java    |  62 +++
 .../apache/river/container/InjectionStyle.java  |  26 +
 .../org/apache/river/container/JarFilter.java   |  43 ++
 .../container/LocalizedRuntimeException.java    | 107 ++++
 .../apache/river/container/MBeanRegistrar.java  |  60 +++
 .../apache/river/container/MessageNames.java    | 124 +++++
 .../java/org/apache/river/container/Name.java   |  37 ++
 .../java/org/apache/river/container/Names.java  |  28 +
 .../org/apache/river/container/Optional.java    |  62 +++
 .../river/container/ProfileConfigReader.java    |  78 +++
 .../river/container/PropertiesFileReader.java   |  79 +++
 .../ServiceStarterArchiveFileFilter.java        |  39 ++
 .../container/SettableCodebaseClassLoader.java  | 153 ++++++
 .../river/container/ShowContextToConsole.java   |  62 +++
 .../org/apache/river/container/Shutdown.java    |  36 ++
 .../river/container/ShutdownListener.java       |  54 ++
 .../river/container/ShutdownListenerMXBean.java |  29 ++
 .../org/apache/river/container/Strings.java     |  80 +++
 .../river/container/SurrogateInstaller.java     |  95 ++++
 .../container/SystemClassloaderInitializer.java |  53 ++
 .../java/org/apache/river/container/Utils.java  | 137 +++++
 .../river/container/classloading/ASTNode.java   |  85 +++
 .../river/container/classloading/Acceptor.java  |  27 +
 .../container/classloading/AllAcceptor.java     |  35 ++
 .../container/classloading/ClasspathEntry.java  |  56 ++
 .../container/classloading/ClasspathFilter.java |  77 +++
 .../classloading/ClasspathFilterBuilder.java    |  94 ++++
 .../classloading/ResourceAcceptor.java          |  92 ++++
 .../river/container/classloading/Strings.java   |  44 ++
 .../VirtualFileSystemClassLoader.java           | 298 +++++++++++
 .../river/container/codebase/ClassServer.java   | 464 +++++++++++++++++
 .../codebase/ClassServerCodebaseContext.java    |  84 +++
 .../container/codebase/CodebaseContext.java     |  46 ++
 .../container/codebase/CodebaseHandler.java     |  39 ++
 .../codebase/DummyCodebaseHandler.java          |  70 +++
 .../river/container/codebase/Strings.java       |  33 ++
 .../river/container/codebase/UUIDEncoder.java   |  32 ++
 .../org/apache/river/container/core-config.xml  |  75 +++
 .../river/container/deployer/ASTNode.java       | 118 +++++
 .../deployer/ApplicationEnvironment.java        |  98 ++++
 .../deployer/ClasspathFilterBuilder.java        | 100 ++++
 .../container/deployer/ServiceLifeCycle.java    |  38 ++
 .../deployer/StarterServiceDeployer.java        | 473 +++++++++++++++++
 .../deployer/StarterServiceDeployerMXBean.java  |  26 +
 .../deployer/StarterServiceLifeCycleSM.java     | 297 +++++++++++
 .../container/deployer/StartupDeployer.java     | 156 ++++++
 .../river/container/deployer/StatusEvents.java  |  36 ++
 .../river/container/deployer/Strings.java       |  31 ++
 .../apache/river/container/el/ArgsParser.java   |  35 ++
 .../river/container/el/ArgsParserImpl.java      |  45 ++
 .../apache/river/container/hsm/Controller.java  |  36 ++
 .../org/apache/river/container/hsm/Guard.java   |  43 ++
 .../org/apache/river/container/hsm/Initial.java |  40 ++
 .../hsm/InvokeAndTransitionOperation.java       |  80 +++
 .../container/hsm/InvokeGuardOperation.java     |  87 ++++
 .../hsm/InvokeVoidAndTransitionOperation.java   |  80 +++
 .../river/container/hsm/MessageNames.java       |  46 ++
 .../apache/river/container/hsm/MetaState.java   | 106 ++++
 .../river/container/hsm/MetaStateVisitor.java   |  13 +
 .../org/apache/river/container/hsm/OnEntry.java |  39 ++
 .../org/apache/river/container/hsm/OnExit.java  |  39 ++
 .../apache/river/container/hsm/Operation.java   |  34 ++
 .../hsm/PlainStateMachineExecutor.java          | 391 ++++++++++++++
 .../apache/river/container/hsm/Retained.java    |  37 ++
 .../apache/river/container/hsm/RootState.java   |  40 ++
 .../org/apache/river/container/hsm/State.java   |  43 ++
 .../container/hsm/StateMachineCompiler.java     | 321 ++++++++++++
 .../container/hsm/StateMachineException.java    | 106 ++++
 .../container/hsm/StateMachineExecutor.java     |  40 ++
 .../river/container/hsm/StateMachineInfo.java   |  15 +
 .../river/container/hsm/SubstateInfo.java       | 109 ++++
 .../apache/river/container/hsm/Transition.java  |  42 ++
 .../container/hsm/TransitionOnSubstate.java     |  40 ++
 .../apache/river/container/liaison/Strings.java |  33 ++
 .../liaison/VirtualFileSystemConfiguration.java | 176 +++++++
 .../container/security/ContainerCodePolicy.java |  76 +++
 .../container/security/SecurityInitializer.java |  67 +++
 .../river/container/work/BasicWorkManager.java  | 135 +++++
 .../container/work/ContextualWorkManager.java   |  73 +++
 .../river/container/work/WorkManager.java       |  65 +++
 .../river/container/work/WorkingContext.java    |  47 ++
 .../main/jjtree/ClasspathExpressionParser.jjt   | 148 ++++++
 .../src/main/jjtree/DeployerConfigParser.jjt    | 413 +++++++++++++++
 .../apache/river/container/Messages.properties  | 115 ++++
 .../river/container/hsm/Messages.properties     |  38 ++
 river-container-core/src/main/xsd/config.xsd    |  91 ++++
 .../container/AnnotatedClassDeployerTest.java   | 258 +++++++++
 .../apache/river/container/BootstrapTest.java   |  63 +++
 .../apache/river/container/CommonsVFSTest.java  | 141 +++++
 .../container/PropertiesFileReaderTest.java     | 134 +++++
 .../classloading/ClasspathFilterParserTest.java | 126 +++++
 .../classloading/VFSClassLoaderTest.java        | 208 ++++++++
 .../container/codebase/SocketAddressTest.java   |  74 +++
 .../config/ConfigurationParserTest.java         |  94 ++++
 .../deployer/DeployerConfigParserTest.java      | 151 ++++++
 .../river/container/el/ArgParserTest.java       |  82 +++
 .../river/container/hsm/HSMTestSuite.java       |  38 ++
 .../container/hsm/InitializedMachineTest.java   | 101 ++++
 .../river/container/hsm/InitializedTestSM.java  |  67 +++
 .../hsm/InitializedTestSMInterface.java         |  34 ++
 .../apache/river/container/hsm/LoggingTest.java |  58 +++
 .../container/hsm/PlainMachineExecutorTest.java | 238 +++++++++
 .../river/container/hsm/ReturnTypeTest.java     |  49 ++
 .../container/hsm/StateMachineCompilerTest.java | 146 ++++++
 .../org/apache/river/container/hsm/TestSM.java  | 150 ++++++
 .../river/container/hsm/TestSMInterface.java    |  50 ++
 .../container/hsm/TestSMSecondInterface.java    |  29 ++
 .../container/security/SecurityManagerTest.java |  85 +++
 .../container/work/BasicWorkManagerTest.java    |  86 +++
 .../work/ContextualWorkManagerTest.java         | 147 ++++++
 .../river/surrogate/SurrogateContextTest.java   |  68 +++
 .../container/config/config-test-bad-doc.xml    |  26 +
 .../river/container/config/config-test-doc.xml  |  26 +
 .../river/container/deployer/sample.config      |  54 ++
 131 files changed, 12208 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..10f4733
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.river</groupId>
+  <artifactId>river-container</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <name>river-container</name>
+  <modules>
+    <module>river-container-core</module>
+  </modules>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/pom.xml
----------------------------------------------------------------------
diff --git a/river-container-core/pom.xml b/river-container-core/pom.xml
new file mode 100644
index 0000000..d99b171
--- /dev/null
+++ b/river-container-core/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.river</groupId>
+        <artifactId>river-container</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <groupId>org.apache.river</groupId>
+    <artifactId>river-container-core</artifactId>
+    <version>1.0-SNAPSHOT</version>
+    <name>river-container-core</name>
+    <url>http://maven.apache.org</url>
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-vfs2</artifactId>
+            <version>2.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.jini</groupId>
+            <artifactId>jsk-platform</artifactId>
+            <version>2.2.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>net.jini</groupId>
+            <artifactId>jsk-resources</artifactId>
+            <version>2.2.1</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>javacc-maven-plugin</artifactId>
+                <version>2.6</version>
+                <executions>
+                    <execution>
+                        <id>jjtree-javacc</id>
+                        <goals>
+                            <goal>jjtree-javacc</goal>
+                        </goals>
+                        <configuration>
+                            <!-- options for JJTree and JavaCC go here -->
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>jaxb2-maven-plugin</artifactId>
+                <version>1.5</version>
+                <executions>
+                    <execution>
+                        <id>xjc</id>
+                        <goals>
+                            <goal>xjc</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <packageName>org.apache.river.container.config</packageName> <!-- The name of your generated source package -->
+                </configuration>
+            </plugin>      
+        </plugins>
+   
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/AbstractConnector.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/AbstractConnector.java b/river-container-core/src/main/java/org/apache/river/container/AbstractConnector.java
new file mode 100644
index 0000000..cbe64c1
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/AbstractConnector.java
@@ -0,0 +1,48 @@
+/*
+ * 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.io.File;
+import java.net.URL;
+
+/**
+ * Defines an abstract connector for the surrogate container.
+ * The connector looks after discovering the device that needs the surrogate,
+ * then loads up the surrogate's jar file and installs the surrogate into the
+ * container.
+ * @author trasukg
+ */
+public class AbstractConnector {
+
+    Host host=null;
+
+    /**
+     * Process the surrogate device's request to host a surrogate, starting
+     * from a URL to the surrogate package.
+     */
+    public void processSurrogateHostingRequest(URL surrogatePackage) {
+        // Allocate a working directory
+        File workingDir=host.newWorkDirectory();
+        
+        SurrogateInstaller installer= (SurrogateInstaller)
+                host.getAttribute(Names.SURROGATE_INSTALLER);
+
+        installer.installSurrogate(host, workingDir);
+    }
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/AnnotatedClassDeployer.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/AnnotatedClassDeployer.java b/river-container-core/src/main/java/org/apache/river/container/AnnotatedClassDeployer.java
new file mode 100644
index 0000000..91b3e0c
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/AnnotatedClassDeployer.java
@@ -0,0 +1,518 @@
+/*
+ * 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.beans.Introspector;
+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>();
+    private List<DeploymentListener> deploymentListeners =
+            new ArrayList<DeploymentListener>();
+
+    public List<DeploymentListener> getDeploymentListeners() {
+        return deploymentListeners;
+    }
+
+    public void put(String name, Object o) {
+        try {
+            /*
+            Scan the object's class and register any injection needs from it.
+             */
+            readInObject(name, o);
+            /* Attempt to satisfy the object's injection needs from current
+            candidates.
+             */
+            resolve();
+        } catch (IllegalArgumentException ex) {
+            throw new ConfigurationException(
+                    ex,
+                    MessageNames.ILLEGAL_ARGUMENT_EXCEPTION);
+        } catch (IllegalAccessException ex) {
+            throw new ConfigurationException(
+                    ex,
+                    MessageNames.ILLEGAL_ACCESS_EXCEPTION);
+        } catch (InvocationTargetException ex) {
+            throw new ConfigurationException(
+                    ex,
+                    MessageNames.INVOCATION_TARGET_EXCEPTION);
+        }
+    }
+
+    public void remove(Object o) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public void setContext(Context ctx) {
+        this.context = ctx;
+    }
+
+    /** 
+    When the context notifies us that it is done reading the initialization
+    file, etc, then we can inject default values, check for unresolved
+    dependencies, etc.
+     */
+    public void initComplete() {
+        checkUnresolvedDependencies();
+    }
+
+    @Override
+    public void shutDown() {
+        for (DeploymentListener l : getDeploymentListeners()) {
+            l.shutDown();
+        }
+    }
+
+    private void checkUnresolvedDependencies() {
+        if (uninitializedObjects.isEmpty()) {
+            return;
+        }
+
+        for (DeployedObject depObj : uninitializedObjects) {
+            for (Member m : depObj.getUnresolvedDependencies()) {
+                log.log(Level.SEVERE,
+                        MessageNames.UNRESOLVED_DEPENDENCY,
+                        new Object[]{depObj.getName(),
+                            m.getName(), nameOfRequiredObject(m)});
+            }
+        }
+        throw new ConfigurationException(MessageNames.ANNOTATED_OBJECT_DEPLOYER_HAS_UNRESOLVED_DEPENDENCIES);
+    }
+
+    /**
+    Given an object, see if it is fully resolved (no outstanding dependencies).
+    If it is, then call any initialization that may be required, and move it
+    to our list of 'ready' objects.
+    @param deployed
+    @return True if the list of 'ready' objects has been changed.
+    @throws IllegalAccessException
+    @throws IllegalArgumentException
+    @throws InvocationTargetException
+     */
+    private boolean initializeIfFullyResolved(DeployedObject deployed) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+        if (deployed.getUnresolvedDependencies().isEmpty()) {
+            if (deployed.isInitialized() == false) {
+
+                uninitializedObjects.remove(deployed);
+                for (Method initMethod : deployed.getInitMethods()) {
+                    initMethod.invoke(deployed.getDeployedObject());
+                }
+                notifyDeploymentListeners(deployed);
+                initializedObjects.put(deployed.getName(), deployed);
+                if (deployed.getDeployedObject() instanceof DeploymentListener) {
+                    deploymentListeners.add((DeploymentListener) deployed.getDeployedObject());
+                }
+                if (!deployed.getShutdownMethods().isEmpty()) {
+                    deploymentListeners.add(new ShutdownRunner(deployed));
+                }
+                deployed.setInitialized(true);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private void notifyDeploymentListeners(DeployedObject deployed) {
+        for (DeploymentListener l : deploymentListeners) {
+            l.postInit(deployed.getName(), deployed.getDeployedObject());
+        }
+    }
+
+    private void readInObject(String name, Object o) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        log.log(Level.FINER,
+                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.log(Level.FINER,
+                MessageNames.READING_OBJECT_MEMBER_COUNT, members.size());
+
+        for (Member m : members) {
+            if (isAnnotatedAsInjected(m)) {
+                log.log(Level.FINER,
+                        MessageNames.READING_OBJECT_ANNOTATED_MEMBER_FOUND, m.toString());
+                unresolved.add(m);
+            }
+            if (isInitMethod(m)) {
+                deployed.getInitMethods().add((Method) m);
+            }
+            if (isShutdownMethod(m)) {
+                deployed.getShutdownMethods().add((Method) m);
+            }
+            if (isAnnotatedAsName(m)) {
+                memberSet(deployed.getDeployedObject(), m, deployed.getName());
+            }
+        }
+        /* Add the object
+        and list to our unsatisfied group. If it has no dependencies, then it
+        will be initialized and moved over to the initialized group when
+        resolve() is called.
+         */
+        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;
+        }
+        Method method = (Method) m;
+        if (method.getReturnType() != void.class) {
+            throw new ConfigurationException(MessageNames.INIT_METHOD_NOT_VOID,
+                    m.getDeclaringClass().getName(),
+                    m.getName(),
+                    method.getReturnType());
+        }
+        if (method.getParameterTypes().length != 0) {
+            throw new ConfigurationException(MessageNames.INIT_METHOD_HAS_PARAMETERS,
+                    m.getDeclaringClass().getName(),
+                    m.getName());
+        }
+        return true;
+    }
+
+    /**
+    It's a shutdown method if it is
+    <ul>
+    <li>a Method</li>
+    <li>is annotated @Shutdown</li>
+    <li>takes no parameter</li>
+    <li>returns void</li>
+    </ul>
+    @param m The method to evaluate.
+    @return
+     */
+    private boolean isShutdownMethod(Member m) {
+        AnnotatedElement annEm = (AnnotatedElement) m;
+        if (annEm.getAnnotation(Shutdown.class) == null) {
+            return false;
+        }
+        Method method = (Method) m;
+        if (method.getReturnType() != void.class) {
+            throw new ConfigurationException(MessageNames.SHUTDOWN_METHOD_NOT_VOID,
+                    m.getDeclaringClass().getName(),
+                    m.getName(),
+                    method.getReturnType());
+        }
+        if (method.getParameterTypes().length != 0) {
+            throw new ConfigurationException(MessageNames.SHUTDOWN_METHOD_HAS_PARAMETERS,
+                    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;
+            } else {
+                throw new ConfigurationException(MessageNames.BAD_MEMBER_FOR_INJECTED_ANNOTATION, m.getDeclaringClass(), m.getName());
+            }
+        }
+        return false;
+    }
+
+    private boolean isAnnotatedAsName(Member m) {
+        AnnotatedElement annEm = (AnnotatedElement) m;
+        if (annEm.getAnnotation(Name.class) != null) {
+            if (m instanceof Field && ((Field) m).getType() == String.class) {
+                return true;
+            }
+            if (m instanceof Method && m.getName().startsWith(Strings.SET)
+                    && ((Method) m).getParameterTypes().length == 1
+                    && ((Method) m).getParameterTypes()[0] == String.class) {
+                return true;
+            } else {
+                throw new ConfigurationException(MessageNames.BAD_MEMBER_FOR_NAME_ANNOTATION, m.getDeclaringClass(), m.getName());
+            }
+        }
+        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;
+    }
+
+    /** Build a list of members that might be candidates for injection.
+    
+    @param cls
+    @return
+    @throws SecurityException
+     */
+    List<Member> buildMemberList(Class cls) throws SecurityException {
+        List<Member> members = new ArrayList<Member>();
+        try {
+        members.addAll(Arrays.asList(cls.getDeclaredMethods()));
+        members.addAll(Arrays.asList(cls.getDeclaredFields()));
+        } catch(Error err) {
+            Utils.logClassLoaderHierarchy(log, cls);
+            throw err;
+        }
+        return members;
+    }
+
+    private void removeDependencyFromUnresolvedList(DeployedObject deployed, Member m) {
+        deployed.getUnresolvedDependencies().remove(m);
+    }
+
+    private void resolve() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        boolean changed;
+        do {
+            changed = false;
+            /* 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)) {
+                changed = resolveDeployedObject(deployed);
+            }
+        } while (changed);
+
+    }
+
+    private boolean resolveDeployedObject(DeployedObject deployed) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        /* Attempt to resolve unsatisfied dependencies. */
+        for (Member m : new ArrayList<Member>(deployed.getUnresolvedDependencies())) {
+            Object val = null;
+            InjectionStyle style = injectionStyle(m);
+
+            if (style == InjectionStyle.BY_NAME) {
+                String name = nameOfRequiredObject(m);
+                DeployedObject deployedCandidate=initializedObjects.get(name);
+                if (deployedCandidate != null) {
+                    val=deployedCandidate.getDeployedObject();
+                }
+            } else if (style==InjectionStyle.BY_TYPE) {
+                /* Find a type-compatible object if name lookup fails. */
+                val = findAssignable(m);
+            }
+            if (val != null) {
+                inject(deployed, m, val);
+                removeDependencyFromUnresolvedList(deployed, m);
+            }
+        }
+        /* If satisfied, remove from unsatisfied group and
+        put into candidate group, then initialize. */
+        boolean changed = initializeIfFullyResolved(deployed);
+        return changed;
+    }
+
+    private InjectionStyle injectionStyle(Member m) {
+        AnnotatedElement annEm = (AnnotatedElement) m;
+        Injected inj = (Injected) annEm.getAnnotation(Injected.class);
+        return inj.style() != InjectionStyle.DEFAULT ? inj.style() : InjectionStyle.BY_NAME;
+    }
+
+    private String nameOfRequiredObject(Member m) {
+        AnnotatedElement annEm = (AnnotatedElement) m;
+        Injected inj = (Injected) annEm.getAnnotation(Injected.class);
+        if (inj.value() != null && !Strings.EMPTY.equals(inj.value())) {
+            return inj.value();
+        }
+        if (m instanceof Field) {
+            return ((Field) m).getName();
+        }
+        if (m instanceof Method) {
+            String methodName = m.getName();
+            if (methodName.startsWith(Strings.SET)) {
+                /* Strip off 'set' and decapitalize the remainder according
+                to JavaBeans spec. */
+                return Introspector.decapitalize(methodName.substring(3));
+            }
+        }
+        return null;
+    }
+
+    /**
+    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();
+        }
+
+        /* Don't do injection by type on value types or String. */
+        if (isSimpleType(requiredType)) {
+            return null;
+        }
+        if (requiredType.isAssignableFrom(Context.class)) {
+            return context;
+        }
+        for (DeployedObject candidate : initializedObjects.values()) {
+            if (requiredType.isAssignableFrom(candidate.getDeployedObject().getClass())) {
+                return candidate.getDeployedObject();
+            }
+        }
+        return null;
+    }
+    private Class[] simpleTypes = {
+        boolean.class,
+        int.class,
+        long.class,
+        float.class,
+        double.class,
+        Boolean.class,
+        Integer.class,
+        Long.class,
+        Float.class,
+        Double.class,
+        java.util.Date.class,
+        String.class
+    };
+
+    private boolean isSimpleType(Class type) {
+        for (Class simpleType : simpleTypes) {
+            if (type == simpleType) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /** 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.log(Level.FINER,
+                MessageNames.INJECT,
+                new Object[]{deployed.getName(), m.getName(), val});
+        memberSet(deployed.getDeployedObject(), m, val);
+    }
+
+    private void memberSet(Object target, Member member, Object value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+        if (member instanceof Field) {
+            Field f = (Field) member;
+            boolean originalAccess = f.isAccessible();
+            f.setAccessible(true);
+            f.set(target, convertProperty(value, f.getType()));
+            f.setAccessible(originalAccess);
+        } else {
+            Method m = (Method) member;
+            boolean originalAccess = m.isAccessible();
+            m.setAccessible(true);
+            m.invoke(target, convertProperty(value, m.getParameterTypes()[0]));
+            m.setAccessible(originalAccess);
+        }
+    }
+
+    private Object convertProperty(Object value, Class requiredType) {
+        /* TODO: Make this a little more flexible and configurable! */
+        if (requiredType.isAssignableFrom(value.getClass())) {
+            return value;
+        }
+        if (requiredType.equals(Integer.class)
+                || requiredType.equals(int.class)) {
+            return Integer.parseInt(value.toString());
+        }
+        throw new LocalizedRuntimeException(MessageNames.BUNDLE_NAME, MessageNames.CANT_CONVERT_EXCEPTION,
+                new Object[]{value.toString(), requiredType.toString()});
+    }
+
+    private class ShutdownRunner implements DeploymentListener {
+
+        private DeployedObject deployedObject = null;
+
+        ShutdownRunner(DeployedObject o) {
+            deployedObject = o;
+        }
+
+        @Override
+        public void postInit(String name, Object object) {
+            // No action.  Handled in upper level.
+        }
+
+        @Override
+        public void shutDown() {
+            for (Method m : deployedObject.getShutdownMethods()) {
+                try {
+                    m.invoke(deployedObject.getDeployedObject(), new Object[0]);
+                } catch (Throwable t) {
+                    // TODO: Figure out what to do here!
+                    t.printStackTrace();
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/AttributeStore.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/AttributeStore.java b/river-container-core/src/main/java/org/apache/river/container/AttributeStore.java
new file mode 100644
index 0000000..ee0bfd9
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/AttributeStore.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+/**
+ Implements an attribute store with some features of an IOC container, plus
+ some security visibility features.
+ * @author trasukg
+ */
+public interface AttributeStore {
+    /**
+     Return the attribute listed under the desired name, assuming that
+     the current code has permission to access that attribute.
+     
+     @param name
+     @return The attribute.
+     */
+    public Object getAttribute(String name);
+
+    /**
+     Store an attribute in the attribute store.
+
+     @param name
+     @param attribute
+     */
+    public void setAttribute(String name, Object attribute);
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/AttributeStoreImpl.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/AttributeStoreImpl.java b/river-container-core/src/main/java/org/apache/river/container/AttributeStoreImpl.java
new file mode 100644
index 0000000..14cc93d
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/AttributeStoreImpl.java
@@ -0,0 +1,52 @@
+/*
+ * 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.security.GuardedObject;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ *
+ * @author trasukg
+ */
+public class AttributeStoreImpl implements AttributeStore {
+
+    private Map<String, Object> attributes=new HashMap<String, Object>();
+
+    /**
+     Retrieve an attribute, checking security permissions if it happens
+     to be a guarded object.
+     @param name
+     @return
+     */
+    public Object getAttribute(String name) {
+        Object attr=attributes.get(name);
+        if (attr instanceof GuardedObject) {
+            return ((GuardedObject) attr).getObject();
+        }
+        return attr;
+    }
+
+    public void setAttribute(String name, Object attribute) {
+        attributes.put(name, attribute);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/Bootstrap.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/Bootstrap.java b/river-container-core/src/main/java/org/apache/river/container/Bootstrap.java
new file mode 100644
index 0000000..d5a2fed
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/Bootstrap.java
@@ -0,0 +1,259 @@
+/*
+ * 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.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.XMLConstants;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import org.apache.river.container.config.*;
+import org.xml.sax.SAXException;
+
+/**
+ Bootstrap loader for the container. Performs roughly the following: <ul>
+ <li>Based on the configuration parameter fed in at the command line, determine
+ the configuration directory and the config file.</li> <li>Read the
+ configuration file</li> <li>Based on the classpath declared in the config file,
+ create the container's classloader.</li> <li>Using that classloader, create the
+ context.</li> <li>Load any command-line parameters into the context</li>
+ <li>Create all the elements (beans, discovery sets, etc) that are called out in
+ the config file and put them into the context. This will cause those beans to
+ setup and initialize themselves.</li> </li>
+
+ @author trasukg
+ */
+public class Bootstrap {
+
+    private static final Logger log =
+            Logger.getLogger(Bootstrap.class.getName(), MessageNames.BUNDLE_NAME);
+
+    public static void main(String args[]) {
+        try {
+            initializeContainer(args);
+        } catch (InvocationTargetException ex) {
+            log.log(Level.SEVERE, MessageNames.INITIALIZATION_EXCEPTION, ex.getCause());
+            ex.printStackTrace();
+            System.exit(-1);
+        } catch (Exception ex) {
+            log.log(Level.SEVERE, MessageNames.INITIALIZATION_EXCEPTION, ex);
+            ex.printStackTrace();
+            System.exit(-1);
+        }
+    }
+
+    static Unmarshaller createConfigUnmarshaller() throws SAXException, JAXBException {
+        JAXBContext ctx = JAXBContext.newInstance("org.apache.river.container.config");
+        Unmarshaller um = ctx.createUnmarshaller();
+        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        Source source = new StreamSource(Bootstrap.class.getResourceAsStream("/schemas/config.xsd"));
+        Schema schema = sf.newSchema(source);
+        um.setSchema(schema);
+        return um;
+    }
+
+    static URL[] findClasspathURLS(String classpathStr) throws MalformedURLException {
+        StringTokenizer tok = new StringTokenizer(classpathStr, Strings.WHITESPACE_SEPARATORS);
+        List<URL> pathElements = new ArrayList<URL>();
+        while (tok.hasMoreTokens()) {
+            File f = new File(tok.nextToken());
+            pathElements.add(f.toURI().toURL());
+        }
+        URL[] urls = (URL[]) pathElements.toArray(new URL[0]);
+        return urls;
+    }
+
+    private static Map<String, ClassLoader> createClassLoaders(ContainerConfig config) throws MalformedURLException {
+
+        Map<String, ClassLoader> classLoaders = new HashMap<String, ClassLoader>();
+        classLoaders.put(Strings.BOOTSTRAP_CLASS_LOADER, Bootstrap.class.getClassLoader());
+        /*
+         Setup the classloaders according to the config file.
+         */
+        List<String> seen = new LinkedList<String>();
+        Map<String, Classpath> classpaths = new HashMap<String, Classpath>();
+        for (Classpath classpath : config.getClasspath()) {
+            if (classpaths.containsKey(classpath.getId())) {
+                throw new ConfigurationException(MessageNames.DUPLICATE_CLASSPATH, classpath.getId());
+            }
+            classpaths.put(classpath.getId(), classpath);
+        }
+
+        for (String id : classpaths.keySet()) {
+            resolveClassLoader(classLoaders, seen, classpaths, id);
+        }
+        return classLoaders;
+    }
+
+    private static ClassLoader resolveClassLoader(Map<String, ClassLoader> classLoaders,
+            List<String> seen,
+            Map<String, Classpath> classpaths,
+            String id) throws MalformedURLException {
+        if (classLoaders.containsKey(id ) ){
+            return classLoaders.get(id);
+        }
+        if (seen.contains(id)) {
+            throw new ConfigurationException(MessageNames.CIRCULAR_CLASSPATH, id);          
+        }
+        // Add the id to the list of classloaders we have attempted to build.
+        seen.add(id);
+        Classpath classpath=classpaths.get(id);
+        if (classpath==null) {
+            throw new ConfigurationException(MessageNames.CLASSPATH_UNDEFINED, id);
+        }
+        String parentClasspathId=classpath.getParent();
+        ClassLoader parentClassLoader=null;
+        if (parentClasspathId!=null && !Strings.EMPTY.equals(parentClasspathId) ){
+            parentClassLoader=resolveClassLoader(classLoaders, seen, classpaths, parentClasspathId);
+        } else {
+            /* Should be the 'extension' classloader. */
+            parentClassLoader=Bootstrap.class.getClassLoader().getParent();
+        }
+        URL[] classpathUrls;
+        classpathUrls = findClasspathURLS(classpath.getValue());
+        
+        SettableCodebaseClassLoader classLoader = new SettableCodebaseClassLoader(classpathUrls,
+                parentClassLoader);
+        classLoaders.put(id, classLoader);
+        log.log(Level.FINE, MessageNames.CONFIGURED_CLASSPATH, new Object[]{
+                    id,
+                    Utils.format(classpathUrls)});
+        seen.remove(id);
+        return classLoader;      
+    }
+
+    static void initializeContainer(String args[]) throws SAXException, JAXBException, FileNotFoundException, MalformedURLException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, ConfigurationException, Exception {
+        //Logger.getLogger("org.apache.river.container.AnnotatedClassDeployer").setLevel(Level.ALL);
+        Logger.getLogger(CommandLineArgumentParser.class.getName()).setLevel(Level.ALL);
+
+        ContainerConfig coreConfig = readCoreConfig();
+        Map<String, ClassLoader> classLoaders = createClassLoaders(coreConfig);
+
+        ClassLoader containerClassLoader = classLoaders.get(Strings.CONTAINER_CLASS_LOADER);
+
+        /*
+         Create the context object.
+         */
+        Object context = Class.forName(Strings.CONTEXT_CLASS, true, containerClassLoader).newInstance();
+        Method putByNameMethod = context.getClass().getMethod(
+                Strings.PUT, new Class[]{String.class, Object.class});
+        Method initCompleteMethod = context.getClass().getMethod(Strings.INIT_COMPLETE, new Class[0]);
+        Thread.currentThread().setContextClassLoader(containerClassLoader);
+        putByNameMethod.invoke(context, Strings.CLASS_LOADERS, (Object) classLoaders);
+        /*
+         Process the core configuration
+         */
+        processConfiguration(coreConfig, containerClassLoader, context);
+        /*
+         We need to set the command line args after processing the core
+         configuration so that the items in the core-config get initialized.
+         */
+        putByNameMethod.invoke(context, Strings.COMMAND_LINE_ARGS, (Object) args);
+        /*
+         The core configuration now loads the profile configuration...
+         */
+        // processConfiguration(containerConfig, classLoader, putMethod, context, putByNameMethod);
+        initCompleteMethod.invoke(context, new Object[0]);
+    }
+
+    static void processConfiguration(ContainerConfig config, Object classLoader, Object context) throws InvocationTargetException, ConfigurationException, IllegalArgumentException, InstantiationException, ClassNotFoundException, IllegalAccessException, NoSuchMethodException, MalformedURLException, Exception {
+        Method putMethod = context.getClass().getMethod(Strings.PUT, new Class[]{Object.class});
+        Method putByNameMethod = context.getClass().getMethod(
+                Strings.PUT, new Class[]{String.class, Object.class});
+
+        /*
+         Add the classpath urls found in the configuration into the classloader.
+         Note that we have to do this by reflection because the classloader
+         we're handed may not be the same classloader that loaded this instance
+         of the Bootstrap class. In particular, this occurs when we are loading
+         the profile configuration by calling out ProfileConfigReader in
+         core-config.xml. In that case, the container classloader is created by
+         the original Bootstrap class inside the original classloader, but
+         ProfileConfigReader and hence another Bootstrap class gets loaded by
+         the container class loader.
+         */
+        /*
+         Not really sure about this.... would be required if we wanted the
+         profile configs to add jar files to the classpath. Not sure if that is
+         really "on", seeing as how we don't really want users attempting to
+         extend the container. Having said that, it's possible that certain
+         deployers might be in a different project, hence different jar files,
+         so we might want to let the profiles add to the classpath. Needs more
+         thought. for (URL url : findClasspathURLS(config)) { new
+         Statement(classLoader, Strings.ADD_URL, new Object[]{url}).execute(); }
+         */
+        for (Object element : config.getElements()) {
+            processElement(element, (ClassLoader) classLoader, putMethod, context, putByNameMethod);
+        }
+    }
+
+    private static ContainerConfig readCoreConfig() throws SAXException, JAXBException, FileNotFoundException {
+        Unmarshaller um = createConfigUnmarshaller();
+        InputStream is = Bootstrap.class.getResourceAsStream(Strings.CORE_CONFIG_XML);
+        ContainerConfig containerConfig = (ContainerConfig) um.unmarshal(is);
+        return containerConfig;
+    }
+
+    private static void processElement(Object element, ClassLoader classLoader, Method putMethod, Object context, Method putByNameMethod) throws ClassNotFoundException, InstantiationException, InvocationTargetException, ConfigurationException, IllegalAccessException, IllegalArgumentException {
+        if (element instanceof Component) {
+            Component c = (Component) element;
+            Class compClass = Class.forName(c.getClazz(), true, classLoader);
+            String name = c.getName();
+            Object instance = compClass.newInstance();
+            if (name == null || name.trim().length() == 0) {
+                putMethod.invoke(context, instance);
+            } else {
+                putByNameMethod.invoke(context, name, instance);
+            }
+        } else if (element instanceof Property) {
+            Property p = (Property) element;
+            putByNameMethod.invoke(context, p.getName(), p.getValue());
+        } else if (element instanceof DiscoveryContextType) {
+            /*
+             Just drop the element into the context under the appropriate name.
+             */
+            DiscoveryContextType dct = (DiscoveryContextType) element;
+            if (dct.getName() == null) {
+                putByNameMethod.invoke(context, Strings.DEFAULT_DISCOVERY_CONTEXT, dct);
+            } else {
+                putByNameMethod.invoke(context, dct.getName(), dct);
+            }
+        } else {
+            throw new ConfigurationException(MessageNames.UNSUPPORTED_ELEMENT, element.getClass().getName());
+        }
+    }
+    /*
+     static URL[] findClasspathURLS(ContainerConfig containerConfig) throws
+     MalformedURLException { String classpathStr =
+     containerConfig.getClasspath(); URL[] urls =
+     findClasspathURLS(classpathStr); return urls; }
+     */
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/CommandLineArgumentParser.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/CommandLineArgumentParser.java b/river-container-core/src/main/java/org/apache/river/container/CommandLineArgumentParser.java
new file mode 100644
index 0000000..19a0356
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/CommandLineArgumentParser.java
@@ -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.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ Processor that sets up various context items according to the command line
+ arguments supplied.
+ <p>
+ For one thing, this sets up the profile according to the first command-line
+ parameter.  If the first parameter is there and does not start with a '-',
+ it is used as the profile name.  Otherwise the profile name is set to
+ 'default'.
+ 
+ * @author trasukg
+ */
+public class CommandLineArgumentParser {
+    private static final Logger log=
+            Logger.getLogger(CommandLineArgumentParser.class.getName(),
+            MessageNames.BUNDLE_NAME);
+
+    @Injected
+    public String[] commandLineArguments=null;
+
+    @Injected(style= InjectionStyle.BY_TYPE)
+    Context context=null;
+
+    @Init
+    public void init() {
+        /* If there is a first argument, and it doesn't begin with '-', then
+        it's a profile name.
+         */
+        String cmdString=Utils.format(commandLineArguments);
+        log.log(Level.FINE, MessageNames.SHOW_COMMAND_LINE_ARGUMENTS, cmdString);
+        if (commandLineArguments.length > 0 && !commandLineArguments[0].startsWith(Strings.DASH)) {
+            String profileName = commandLineArguments[0];
+            context.put(Strings.PROFILE, profileName);
+        } else {
+            context.put(Strings.PROFILE, Strings.DEFAULT);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/ConfigurationException.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/ConfigurationException.java b/river-container-core/src/main/java/org/apache/river/container/ConfigurationException.java
new file mode 100644
index 0000000..d743bfe
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/ConfigurationException.java
@@ -0,0 +1,34 @@
+/*
+ * 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);
+   }
+
+   public ConfigurationException(Throwable rootCause, String messageKey, Object ... parameters) {
+       super(rootCause, MessageNames.BUNDLE_NAME, messageKey, parameters);
+   }
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/Context.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/Context.java b/river-container-core/src/main/java/org/apache/river/container/Context.java
new file mode 100644
index 0000000..bbf2de6
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/Context.java
@@ -0,0 +1,84 @@
+/*
+ * 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 {
+    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: new ArrayList<ContextListener>(listeners)) {
+            l.put(name, o);
+        }
+    }
+
+    /** 
+    Retrieve an object from the context.
+    @param name Name of the object.
+    @return 
+    */
+    public Object get(String name) {
+        return contents.get(name);
+    }
+    
+    /**
+     Called by the bootstrapper to tell us that processing of the initialization
+     file is now complete.
+     */
+    public void initComplete() {
+        for (ContextListener l: listeners) {
+            l.initComplete();
+        }
+
+    }
+    
+    public void shutDown() {
+        for(ContextListener l:listeners) {
+            l.shutDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/ContextListener.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/ContextListener.java b/river-container-core/src/main/java/org/apache/river/container/ContextListener.java
new file mode 100644
index 0000000..243374f
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/ContextListener.java
@@ -0,0 +1,56 @@
+/*
+ * 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 {
+
+    /**
+     Indicates that an object has been added to the context.
+     @param name
+     @param o
+     */
+    public void put(String name, Object o);
+
+    /**
+     Indicates that an object has been removed from the context.
+     @param o
+     */
+    public void remove(Object o);
+
+    /**
+     Informs the listener of the context object.
+     @param ctx
+     */
+    public void setContext(Context ctx);
+
+    /**
+     Indicates that processing of any initialization file is complete.
+     */
+    public void initComplete();
+    
+    /**
+    Indicates that the container is shutting down, so all resources should
+    be closed and/or released.
+    */
+    public void shutDown();
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/DeployedObject.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/DeployedObject.java b/river-container-core/src/main/java/org/apache/river/container/DeployedObject.java
new file mode 100644
index 0000000..cf58b15
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/DeployedObject.java
@@ -0,0 +1,76 @@
+/*
+ * 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.lang.reflect.Method;
+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<Method> initMethods=new ArrayList<Method>();
+    private List<Method> shutdownMethods=new ArrayList<Method>();
+
+    public List<Method> getShutdownMethods() {
+        return shutdownMethods;
+    }
+
+    private boolean initialized=false;
+
+    public boolean isInitialized() {
+        return initialized;
+    }
+
+    public void setInitialized(boolean isInitialized) {
+        this.initialized = isInitialized;
+    }
+    
+    public List<Method> 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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/DeploymentListener.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/DeploymentListener.java b/river-container-core/src/main/java/org/apache/river/container/DeploymentListener.java
new file mode 100644
index 0000000..2e9cf91
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/DeploymentListener.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.river.container;
+
+/**
+ *
+ * @author trasukg
+ */
+public interface DeploymentListener {
+    public void postInit(String name, Object object);
+    
+    public void shutDown();
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/FileUtility.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/FileUtility.java b/river-container-core/src/main/java/org/apache/river/container/FileUtility.java
new file mode 100644
index 0000000..aa3dfbf
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/FileUtility.java
@@ -0,0 +1,49 @@
+/*
+ * 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.io.IOException;
+import org.apache.commons.vfs2.FileObject;
+
+/**
+ * Utilities for dealing with the files and file systems that the
+ River Container uses.  This class builds on Apache Commons-vfs and uses
+ many of its facilities and classes.
+ * @author trasukg
+ */
+public interface FileUtility {
+    /**
+     Get a working directory with the given name.
+     @param name
+     @return
+     @throws IOException
+     */
+    public FileObject getWorkingDirectory(String name) throws IOException;
+
+    /**
+     Get the 'home' directory for the current container profile.
+     @return
+     @throws IOException
+     */
+    public FileObject getProfileDirectory() throws IOException;
+
+    public FileObject getLibDirectory() throws IOException;
+
+    
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/FileUtilityImpl.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/FileUtilityImpl.java b/river-container-core/src/main/java/org/apache/river/container/FileUtilityImpl.java
new file mode 100644
index 0000000..7b88b19
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/FileUtilityImpl.java
@@ -0,0 +1,63 @@
+/*
+ * 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.io.File;
+import java.io.IOException;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+
+/**
+ *
+ * @author trasukg
+ */
+public class FileUtilityImpl implements FileUtility {
+
+    @Injected
+    private String profile=null;
+
+    private FileSystemManager fsm=null;
+
+    public FileObject getWorkingDirectory(String name) throws IOException {
+
+        FileObject workDir=getProfileDirectory().resolveFile(Strings.WORK).resolveFile(name);
+        if (!workDir.exists()) {
+            workDir.createFolder();
+        }
+        return workDir;
+    }
+
+    public FileObject getProfileDirectory() throws IOException {
+        FileObject profileDir = fsm.resolveFile(new File(Strings.PROFILE), profile);
+        return profileDir;
+    }
+
+    @Init
+    public void init() throws FileSystemException {
+        fsm=VFS.getManager();
+    }
+
+    @Override
+    public FileObject getLibDirectory() throws IOException {
+        FileObject libDir = fsm.resolveFile(new File(Strings.LIB), ".");
+        return libDir;
+    }
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/Host.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/Host.java b/river-container-core/src/main/java/org/apache/river/container/Host.java
new file mode 100644
index 0000000..c5ce6b1
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/Host.java
@@ -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.river.container;
+
+import org.apache.river.container.deployer.ApplicationEnvironment;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is from the early work on the surrogate host and was meant to be
+ the overall container.  At this point, it probably should be refactored or
+ removed and replaced with something that supports the Context-based deployers.
+
+ * @author trasukg
+ */
+public class Host {
+
+    List<ApplicationEnvironment> applications = new ArrayList();
+
+    AttributeStore attributeStore=new AttributeStoreImpl();
+
+    public AttributeStore getAttributeStore() {
+        return attributeStore;
+    }
+
+    public List<ApplicationEnvironment> getApplications() {
+        return applications;
+    }
+
+    File newWorkDirectory() {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    /**
+     Create a new application environment and add it to the applications
+     list in the Host.
+     @return The newly-created ApplicationEnvironment.
+     */
+    public ApplicationEnvironment newApplicationEnvironment() {
+        ApplicationEnvironment appEnv=new ApplicationEnvironment();
+        applications.add(appEnv);
+        return appEnv;
+    }
+
+    /**
+     Looks up an attribute in the attribute set.
+     @param name
+     @return
+     */
+    public Object getAttribute(String name) {
+        return getAttributeStore().getAttribute(name);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/Init.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/Init.java b/river-container-core/src/main/java/org/apache/river/container/Init.java
new file mode 100644
index 0000000..4dbe1a4
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/Init.java
@@ -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 {
+
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/Injected.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/Injected.java b/river-container-core/src/main/java/org/apache/river/container/Injected.java
new file mode 100644
index 0000000..3c6d07a
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/Injected.java
@@ -0,0 +1,62 @@
+/*
+ * 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 value() default Strings.EMPTY;
+    InjectionStyle style() default InjectionStyle.DEFAULT;
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/InjectionStyle.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/InjectionStyle.java b/river-container-core/src/main/java/org/apache/river/container/InjectionStyle.java
new file mode 100644
index 0000000..ee2c2cf
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/InjectionStyle.java
@@ -0,0 +1,26 @@
+/*
+ * 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 enum InjectionStyle {
+    BY_NAME, BY_TYPE, DEFAULT;
+}

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/JarFilter.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/JarFilter.java b/river-container-core/src/main/java/org/apache/river/container/JarFilter.java
new file mode 100644
index 0000000..3bb34b4
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/JarFilter.java
@@ -0,0 +1,43 @@
+/*
+ * 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.io.File;
+import java.io.FileFilter;
+
+/**
+ *
+ * @author trasukg
+ */
+public class JarFilter implements FileFilter {
+
+    public boolean accept(File file) {
+        if (!file.isFile()) {
+            return false;
+        }
+        if (!file.canRead()) {
+            return false;
+        }
+        String name = file.getName();
+        if (!name.endsWith(".jar")) {
+            return false;
+        }
+        return true;
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/river-container/blob/9ab01093/river-container-core/src/main/java/org/apache/river/container/LocalizedRuntimeException.java
----------------------------------------------------------------------
diff --git a/river-container-core/src/main/java/org/apache/river/container/LocalizedRuntimeException.java b/river-container-core/src/main/java/org/apache/river/container/LocalizedRuntimeException.java
new file mode 100644
index 0000000..8c11e06
--- /dev/null
+++ b/river-container-core/src/main/java/org/apache/river/container/LocalizedRuntimeException.java
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+    public String getMessageBundleName() {
+        return messageBundleName;
+    }
+
+    public String getMessageKey() {
+        return messageKey;
+    }
+
+    public Object[] getMessageParameters() {
+        return messageParameters;
+    }
+    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;
+    }
+
+    /**
+     Construct a runtime exception with a localized message.
+     @param messageBundleName
+     @param messageKey
+     @param messageParameters
+     */
+    public LocalizedRuntimeException(Throwable rootCause,
+            String messageBundleName,
+            String messageKey,
+            Object ... messageParameters) {
+        super(rootCause);
+        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);
+    }
+}


Mime
View raw message