cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From serg...@apache.org
Subject svn commit: r690991 [17/20] - in /cxf/sandbox/dosgi: ./ discovery/ discovery/local/ discovery/local/src/ discovery/local/src/main/ discovery/local/src/main/java/ discovery/local/src/main/java/org/ discovery/local/src/main/java/org/apache/ discovery/loc...
Date Mon, 01 Sep 2008 15:08:10 GMT
Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/Discovery.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/Discovery.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/Discovery.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/Discovery.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,187 @@
+/*
+ * $Date$
+ *
+ * Copyright (c) OSGi Alliance (2004, 2007). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.discovery;
+
+import java.util.Collection;
+
+
+/**
+ * 
+ * TODO: How to update published ServiceDescriptions? How to identify ServiceDescriptions of the same service instance?
+ * TODO: how about to rename auto-publish to push/pull?
+ * 
+ * @version $Revision$
+ */
+public interface Discovery {
+    final String ORG_OSGI_DISCOVERY = "org.osgi.discovery";
+    final String ORG_OSGI_DISCOVERY_NONE = "none";
+    final String ORG_OSGI_DISCOVERY_AUTO_PUBLISH = "auto-publish";
+        
+        
+    /**
+     * Add a ServiceListener for a particular service description. 
+     * 
+     * @param serviceDescription describes the service(s) to listen for. If serviceDescription is <code>null</code> 
+     * then all services are considered.
+     * @param listener which is to call when discovery detects changes in availability or description of a service. 
+     * The same listener object may also be used to listen on multiple serviceDescription objects.
+     */
+    void addServiceListener(ServiceListener listener, ServiceDescription serviceDescription);
+    
+        
+    /**
+     * Add a ServiceListener for a particular service description. 
+     * 
+     * @param filter an LDAP filter which the service has to satisfy.
+     * @param listener which is to call when discovery detects changes in a service's availability or description. 
+     * The same listener object might also be used for multiple serviceDescription objects.
+     */
+    void addServiceListener(ServiceListener listener, String filter);
+
+    
+    /**
+     * This method is the same as calling
+     * <code>Discovery.addServiceListener(ServiceListener listener, ServiceDescription serviceDescription)</code>
+     * with <code>serviceDescription</code> set to <code>null</code>.
+     * 
+     * @param listener which is to call when discovery detects changes in availability or description of a service. 
+     * The same listener object may also be used to listen on multiple serviceDescription objects.
+     * @see #addServiceListener(ServiceListener, ServiceDescription) 
+     */
+    void addServiceListener(ServiceListener listener);
+    
+    
+    /**
+     * Removes a ServiceListener. 
+     *  
+     * @param listener to remove. If that listener object haven't been added before, then the method returns without throwing exceptions. 
+     */
+    void removeServiceListener(ServiceListener listener);
+        
+        
+    /**
+     * Looks for the given ServiceDescription in the cache. Cache might be local or global depending on the
+     * cache strategy of the Discovery.<b>
+     *      
+     * @param serviceDescription to check for its existence in cache
+     * @return true if a service matching the given serviceDescription is found in the local cache
+     * @throws IllegalArgumentException if serviceDescription is null or incomplete
+     */
+    boolean isCached(ServiceDescription serviceDescription);
+    
+    
+    /**
+     * Returns an array of all ServiceDescription objects currently known to the Discovery implementation.
+     * 
+     * @return A collection of ServiceDescription objects. An empty collection is returned if no service descriptions
+     * were found.
+     */
+    Collection getCachedServiceDescriptions();
+    
+                
+        /**
+         * Searches for services matching the criteria provided with the service description. Matching means in this context 
+         * a containment and not an equality relation though Discovery might choose to ignore some properties if it can't really compare them 
+         * e.g. if a property of the provided service description is a File object (wsdl file for instance).
+         * For this reason its recommended to provide only simple properties with the service description object. 
+         * Any other, more complex matching operations could be done in the next step and are caller's responsibility.
+         *  
+         * @param serviceDescription ServiceDescription of the service to locate
+         * @return Collection of ServiceDescription objects satisfying the find criteria.
+         *         The Collection may be empty if none was found
+         * @throws IllegalArgumentException if serviceDescription is null.
+         */
+        Collection findService(ServiceDescription serviceDescription);
+        
+    
+    /**
+     * Find a service based on the provided LDAP filter. 
+     * 
+     * @param filter an LDAP filter which the service has to satisfy.
+     * @return Collection of ServiceDescription objects matching the service that was found to satisfy the find criteria.
+     *         The Collection may be empty if none was found.
+     * @throws IllegalArgumentException if serviceDescription is null or incomplete
+     * @throws UnsupportedOperationException if method is not supported by the implementation
+     */
+    Collection findService(String filter);
+        
+    
+    /**
+     * Asynchronous version of <code>Discovery.findService(ServiceDescription serviceDescription)</code> method.
+     * 
+     * @param serviceDescription ServiceDescription of the service to locate
+     * @param callback to notify about the asynchronous response of the find operation
+     * @throws IllegalArgumentException if the serviceDescription or callback is null
+     * @see #findService(ServiceDescription) 
+     */
+    void findService(ServiceDescription serviceDescription, FindServiceCallback callback);
+  
+    
+    /**
+     * Asynchronous interface to initiate the search for an suitable service based on the provided ServiceDescription and filter.
+     * Discovery implementations might choose to not support this method if the discovery protocol doesn't support filtering.
+     * The ServiceDescription is matched using the Comparable interface.
+     * 
+     * @param filter an LDAP filter which the service has to satisfy.
+     * @param callback Listener object to notify about the asynchronous response of the find operation
+     * @throws IllegalArgumentException if the serviceDescription is null or incomplete
+     * @throws UnsupportedOperationException if method is not supported by the implementation
+     */
+    void findService(String filter, FindServiceCallback callback);
+    
+    
+    /**
+     * Publish the provided service description.  
+     * If the property org.osgi.discovery = auto-publish, the Discovery implementation actively pushes the
+     * information about the service to the network. Otherwise, it is just available upon request from other
+     * Discovery implementations.
+     * 
+     * @param serviceDescription ServiceDescription of the service to publish
+     * @return true if the service was successfully published.
+     * @throws IllegalArgumentException if serviceDescription is null, incomplete or invalid (e.g. contains 
+     * unknown property types)
+     */
+    boolean publishService(ServiceDescription serviceDescription);
+
+    
+    /**
+     * Publish the provided service. The information is published by the Discovery implementation.<b>
+     * If the parameter autopublish=true, the Discovery implementation actively pushes the
+     * information about the service to the network. Otherwise, it is just available upon request from other
+     * Discovery implementations.
+     * The ServiceDescription is matched using the Comparable interface.
+     * @param serviceDescription ServiceDescription of the service to publish
+     * @param autopublish if true, service information is actively pushed to the network for discovery
+     * @return true if the service was successfully published.
+     * @throws IllegalArgumentException if serviceDescription is null, incomplete or invalid (e.g. contains 
+     * unknown property types)
+     */
+    boolean publishService(ServiceDescription serviceDescription, boolean autopublish);
+    
+    
+    /**
+     * Make the given service un-discoverable. The previous publish request for a service is undone. The service
+     * information is also removed from the local or global cache if cached before.
+     * 
+     * @param serviceDescription ServiceDescription of the service to unpublish. If this ServiceDescription 
+     * haven't been published before, then the method returns without throwing exceptions.
+     * @throws IllegalArgumentException if serviceDescription is null or incomplete
+     */
+    void unpublishService(ServiceDescription serviceDescription);
+}

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/Discovery.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/Discovery.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/FindServiceCallback.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/FindServiceCallback.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/FindServiceCallback.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/FindServiceCallback.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,34 @@
+/*
+ * $Date$
+ *
+ * Copyright (c) OSGi Alliance (2004, 2007). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.discovery;
+
+import java.util.Collection;
+
+ /** 
+ * 
+ * 
+ * @version $Revision$
+ */
+public interface FindServiceCallback {
+    /**
+     * @param serviceDescriptions Collection of ServiceDescription objects satisfying the find criteria.
+     * The Collection may be empty if none was found.
+     */
+    void servicesFound(Collection serviceDescriptions);
+}

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/FindServiceCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/FindServiceCallback.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceDescription.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceDescription.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceDescription.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceDescription.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,104 @@
+/*
+ * $Date$
+ *
+ * Copyright (c) OSGi Alliance (2004, 2007). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.discovery;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * The ServiceDescription interface defines the service and its properties. The main information necessary is the
+ * name of the provided interface.<p/>
+ * 
+ * It's strongly recommended to override <code>Object.equals<code> method to implement an appropriate equivalence 
+ * comparison for ServiceDescription objects. 
+ * 
+ * @version $Revision$
+ */
+public interface ServiceDescription {
+        
+    /**
+     * If value of <code>getInterfaceName</code> needs to be described as a key-value pair e.g. by the discovery 
+     * protocol, filter for discovery etc. and there is no other key standardized for that purpose yet, then this is the 
+     * recommended property key to use. 
+     */    
+    public final String PROP_KEY_INTERFACE_NAME = "interface-name";
+    
+    /**
+     * If value of <code>getProtocolSpecificInterfaceName</code> needs to be described as a key-value pair e.g. by the discovery 
+     * protocol, filter for discovery etc. and there is no other key standardized for that purpose yet, then this is the 
+     * recommended property key to use. 
+     */    
+    public final String PROP_KEY_PROTOCOL_SPECIFIC_INTERFACE_NAME = "protocol-interface-name";
+    
+    /**
+     * If value of <code>getVersion</code> needs to be described as a key-value pair e.g. by the discovery 
+     * protocol, filter for discovery etc. and there is no other key standardized for that purpose yet, then this is the 
+     * recommended property key to use. 
+     */    
+    public final String PROP_KEY_VERSION = "version";
+    
+    /**
+     * If value of <code>getServiceLocation</code> needs to be described as a key-value pair e.g. by the discovery 
+     * protocol, filter for discovery etc. and there is no other key standardized for that purpose yet, then this is the 
+     * recommended property key to use. 
+     */    
+    public final String PROP_KEY_SERVICE_LOCATION = "location";
+    
+    /**
+         * @return The full qualified service interface name
+         */
+        String getInterfaceName();
+        
+        /**
+     * @return The protocol specific service interface name.   It might be for instance a web service interface name. 
+     * Though this information is usually contained in according interface descriptions, e.g. a wsdl file, 
+     * it might be provided here as well since discovery usually doesn't read and interprets such accompanying 
+     * descriptions. 
+     */
+    String getProtocolSpecificInterfaceName();
+    
+    /**
+     * @return The service interface/implementation version.
+     */
+    String getVersion();
+    
+    /**
+     * @return The URL of the service location.
+     */
+    URL getLocation();  
+        
+    /**
+     * Getter method for the property value of a given key.
+     * 
+     * @param key Name of the property
+     * @return The property value, null if none is found for the given key
+     */
+    Object getProperty(String key);
+    
+    /**
+     * @return <code>java.util.Collection</code> of the property names available in the ServiceDescription
+     */
+    Collection getPropertyKeys();
+    
+    /**
+     * @return Returns all properties of the service as a <code>java.util.Map</code>.
+     */
+    Map getProperties();
+}

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceDescription.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceDescription.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceListener.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceListener.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceListener.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceListener.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,46 @@
+/*
+ * $Date$
+ *
+ * Copyright (c) OSGi Alliance (2004, 2007). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.discovery;
+
+/**
+ *
+ * TODO: consider whether methods should also contain a source object (the particular discovery service which does the notification)
+ * 
+ * @version $Revision$
+ */
+public interface ServiceListener {
+    /**
+     * Callback indicating that the specified service was discovered and is known to the calling Discovery implementation.
+     * @param serviceDescription
+     */
+    void serviceAvailable(ServiceDescription serviceDescription);
+    
+    /**
+     * Callback indicating a change in the service description of a previously discovered service.
+     * @param oldDescription previous service description
+     * @param newDescription new service description
+     */
+    void serviceModified(ServiceDescription oldDescription, ServiceDescription newDescription);
+    
+    /**
+     * Callback indicating that the specified service is no longer available/
+     * @param serviceDescription ServiceDescription of the service that is no longer available
+     */
+    void serviceUnavailable(ServiceDescription serviceDescription);
+}

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/discovery/ServiceListener.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/dsw/DistributionProvider.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/dsw/DistributionProvider.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/dsw/DistributionProvider.java (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/dsw/DistributionProvider.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,30 @@
+/*
+ * $Date$
+ *
+ * Copyright (c) OSGi Alliance (2004, 2007). All Rights Reserved.
+ *
+ * Licensed 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.osgi.service.dsw;
+
+import java.util.Map;
+
+import org.osgi.framework.ServiceReference;
+
+public interface DistributionProvider {
+
+    ServiceReference[] getRemoteServices();
+    ServiceReference[] getPublishedServices();
+    
+    Map getPublicationProperties(ServiceReference sr);
+}

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/dsw/DistributionProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/java/org/osgi/service/dsw/DistributionProvider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/framework/src/main/resources/org/apache/felix/framework/Felix.properties
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/framework/src/main/resources/org/apache/felix/framework/Felix.properties?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/framework/src/main/resources/org/apache/felix/framework/Felix.properties (added)
+++ cxf/sandbox/dosgi/felix/framework/src/main/resources/org/apache/felix/framework/Felix.properties Mon Sep  1 08:08:01 2008
@@ -0,0 +1 @@
+felix.version=${pom.version}

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/resources/org/apache/felix/framework/Felix.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/resources/org/apache/felix/framework/Felix.properties
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/sandbox/dosgi/felix/framework/src/main/resources/org/apache/felix/framework/Felix.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/sandbox/dosgi/felix/main/LICENSE
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/main/LICENSE?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/main/LICENSE (added)
+++ cxf/sandbox/dosgi/felix/main/LICENSE Mon Sep  1 08:08:01 2008
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.

Propchange: cxf/sandbox/dosgi/felix/main/LICENSE
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/main/LICENSE
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/sandbox/dosgi/felix/main/NOTICE
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/main/NOTICE?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/main/NOTICE (added)
+++ cxf/sandbox/dosgi/felix/main/NOTICE Mon Sep  1 08:08:01 2008
@@ -0,0 +1,26 @@
+Apache Felix Main
+Copyright 2008 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright 2006 The OSGi Alliance.
+Licensed under the Apache License 2.0.
+
+
+II. Used Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright 2006 The OSGi Alliance.
+Licensed under the Apache License 2.0.
+
+
+III. License Summary
+- Apache License 2.0

Propchange: cxf/sandbox/dosgi/felix/main/NOTICE
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/main/NOTICE
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/sandbox/dosgi/felix/main/etc/logging.properties
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/main/etc/logging.properties?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/main/etc/logging.properties (added)
+++ cxf/sandbox/dosgi/felix/main/etc/logging.properties Mon Sep  1 08:08:01 2008
@@ -0,0 +1,7 @@
+handlers= java.util.logging.ConsoleHandler
+.level= INFO
+org.springframework.level= WARNING
+
+java.util.logging.ConsoleHandler.level= INFO
+java.util.logging.ConsoleHandler.formatter= java.util.logging.SimpleFormatter
+

Propchange: cxf/sandbox/dosgi/felix/main/etc/logging.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/main/etc/logging.properties
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/sandbox/dosgi/felix/main/etc/logging.properties
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/sandbox/dosgi/felix/main/pom.xml
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/main/pom.xml?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/main/pom.xml (added)
+++ cxf/sandbox/dosgi/felix/main/pom.xml Mon Sep  1 08:08:01 2008
@@ -0,0 +1,253 @@
+<!--
+ 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.
+-->
+<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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <name>CXF-Distributed OSGi Temporary Private Felix Main Build</name>
+  <groupId>org.apache.felix</groupId> 
+  <artifactId>org.apache.felix.main</artifactId>
+  <version>1.1.0-cxf_dosgi-SNAPSHOT</version>
+
+  <parent>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-dosgi-ri-parent</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <relativePath>../../parent/pom.xml</relativePath>
+  </parent>
+
+   <properties>
+      <property name="install.home" value="${basedir.absolutePath}" />
+      <topDirectoryLocation>../..</topDirectoryLocation>
+      <maven.test.skip>true</maven.test.skip> 
+      <felix.log.level>1</felix.log.level>
+   </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.framework</artifactId>
+      <version>1.1.0-cxf_dosgi-SNAPSHOT</version>
+      <exclusions>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.core</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.compendium</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.shell</artifactId>
+      <version>1.0.1</version>
+      <exclusions>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.core</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.shell.tui</artifactId>
+      <version>1.1.0-cxf_dosgi-SNAPSHOT</version>
+      <exclusions>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.core</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.bundlerepository</artifactId>
+      <version>1.0.3</version>
+      <exclusions>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.core</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.service.obr</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>net.sf.kxml</groupId>
+          <artifactId>kxml2</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.configadmin</artifactId>
+      <version>1.0.1</version>
+      <exclusions>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.compendium</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>${pom.groupId}</groupId>
+          <artifactId>org.osgi.core</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-checkstyle-plugin</artifactId>
+          <configuration>
+             <excludes>**/*.java</excludes>
+          </configuration>
+      </plugin>
+      <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-pmd-plugin</artifactId>
+          <configuration>
+             <excludes>
+                 <exclude>**/*.java</exclude>
+             </excludes>
+          </configuration>
+      </plugin> 
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <_donotcopy>(CVS|.svn|config.properties)</_donotcopy>
+            <Main-Class>org.apache.felix.main.Main</Main-Class>
+            <Bundle-Name>Apache Felix</Bundle-Name>
+            <Bundle-Description>OSGi R4 framework.</Bundle-Description>
+            <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
+            <Private-Package>org.apache.felix.main.*,org.apache.felix.moduleloader.*;-split-package:=merge-first,org.apache.felix.framework.*;-split-package:=merge-first,org.osgi.framework;-split-package:=merge-first,org.osgi.framework.hooks.service;-split-package:=merge-first,org.osgi.service.packageadmin;-split-package:=merge-first,org.osgi.service.startlevel;-split-package:=merge-first,org.osgi.service.url;-split-package:=merge-first,org.osgi.service.discovery;-split-package:=merge-first,org.osgi.service.dsw;-split-package:=merge-first,org.osgi.util.tracker;-split-package:=merge-first</Private-Package>
+            <Import-Package>!*</Import-Package>
+<Include-Resource>META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,{src/main/resources/}</Include-Resource>
+            <!-- Include these properties here because we want them
+                 substituted in the default.properties resource file
+                 so that we only have to maintain one set of properties
+                 and only for that reason. -->
+            <_include>src/main/resources/config.properties</_include>
+            <dollar>$</dollar>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>validate</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+               <outputDirectory>${project.build.outputDirectory}</outputDirectory>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>${pom.groupId}</groupId>
+                  <artifactId>org.apache.felix.framework</artifactId>
+                  <version>1.1.0-cxf_dosgi-SNAPSHOT</version>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+          <execution>
+            <id>copy</id>
+            <phase>install</phase>
+            <goals>
+              <goal>copy</goal>
+            </goals>
+            <configuration>
+                <artifactItems>
+                  <artifactItem>
+                     <groupId>${pom.groupId}</groupId>
+                     <artifactId>org.apache.felix.shell</artifactId>
+                     <version>1.0.1</version>
+                     <type>jar</type>
+                     <overWrite>true</overWrite>
+                     <outputDirectory>${project.build.directory}/bundle</outputDirectory>
+                   </artifactItem>
+                   <artifactItem>
+                     <groupId>${pom.groupId}</groupId>
+                     <artifactId>org.apache.felix.shell.tui</artifactId>
+                     <version>1.1.0-cxf_dosgi-SNAPSHOT</version>
+                     <type>jar</type>
+                     <overWrite>true</overWrite>
+                     <outputDirectory>${project.build.directory}/bundle</outputDirectory>
+                   </artifactItem>
+                   <artifactItem>
+                     <groupId>${pom.groupId}</groupId>
+                     <artifactId>org.apache.felix.bundlerepository</artifactId>
+                     <version>1.0.3</version>
+                     <type>jar</type>
+                     <overWrite>true</overWrite>
+                     <outputDirectory>${project.build.directory}/bundle</outputDirectory>
+                   </artifactItem>
+                   <artifactItem>
+                     <groupId>${pom.groupId}</groupId>
+                     <artifactId>org.apache.felix.configadmin</artifactId>
+                     <version>1.0.1</version>
+                     <type>jar</type>
+                     <overWrite>true</overWrite>
+                     <outputDirectory>${project.build.directory}/bundle</outputDirectory>
+                   </artifactItem>
+                 </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-antrun-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>install</phase>
+            <configuration>
+              <tasks>
+                <delete dir="${basedir}/bin" />
+                <mkdir dir="${basedir}/bin" />
+                <delete dir="${basedir}/conf" />
+                <mkdir dir="${basedir}/conf" />
+                <delete dir="${basedir}/bundle" />
+                <copy file="${basedir}/target/org.apache.felix.main-${pom.version}.jar" tofile="${basedir}/bin/felix.jar" />
+                <copy file="${basedir}/target/classes/config.properties" todir="${basedir}/conf" />
+                <move file="${basedir}/target/bundle" todir="${basedir}" />
+              </tasks>
+            </configuration>
+            <goals>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources> 
+  </build>
+</project>

Propchange: cxf/sandbox/dosgi/felix/main/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/main/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/sandbox/dosgi/felix/main/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/AutoActivator.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/AutoActivator.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/AutoActivator.java (added)
+++ cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/AutoActivator.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,213 @@
+/*
+ * 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.felix.main;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.startlevel.StartLevel;
+
+public class AutoActivator implements BundleActivator
+{
+    /**
+     * The property name prefix for the launcher's auto-install property.
+    **/
+    public static final String AUTO_INSTALL_PROP = "felix.auto.install";
+    /**
+     * The property name prefix for the launcher's auto-start property.
+    **/
+    public static final String AUTO_START_PROP = "felix.auto.start";
+
+    private Map m_configMap;
+
+    public AutoActivator(Map configMap)
+    {
+        m_configMap = configMap;
+    }
+
+    /**
+     * Used to instigate auto-install and auto-start configuration
+     * property processing via a custom framework activator during
+     * framework startup.
+     * @param context The system bundle context.
+    **/
+    public void start(BundleContext context)
+    {
+        processAutoProperties(context);
+    }
+
+    /**
+     * Currently does nothing as part of framework shutdown.
+     * @param context The system bundle context.
+    **/
+    public void stop(BundleContext context)
+    {
+        // Do nothing.
+    }
+
+    /**
+     * <p>
+     * Processes the auto-install and auto-start properties from the
+     * specified configuration properties.
+     * </p>
+     */
+    private void processAutoProperties(BundleContext context)
+    {
+        // Retrieve the Start Level service, since it will be needed
+        // to set the start level of the installed bundles.
+        StartLevel sl = (StartLevel) context.getService(
+            context.getServiceReference(org.osgi.service.startlevel.StartLevel.class.getName()));
+
+        // Retrieve all auto-install and auto-start properties and install
+        // their associated bundles. The auto-install property specifies a
+        // space-delimited list of bundle URLs to be automatically installed
+        // into each new profile, while the auto-start property specifies
+        // bundles to be installed and started. The start level to which the
+        // bundles are assigned is specified by appending a ".n" to the
+        // property name, where "n" is the desired start level for the list
+        // of bundles. If no start level is specified, the default start
+        // level is assumed.
+        for (Iterator i = m_configMap.keySet().iterator(); i.hasNext(); )
+        {
+            String key = (String) i.next();
+
+            // Ignore all keys that are not an auto property.
+            if (!key.startsWith(AUTO_INSTALL_PROP) && !key.startsWith(AUTO_START_PROP))
+            {
+                continue;
+            }
+
+            // If the auto property does not have a start level,
+            // then assume it is the default bundle start level, otherwise
+            // parse the specified start level.
+            int startLevel = sl.getInitialBundleStartLevel();
+            if (!key.equals(AUTO_INSTALL_PROP) && !key.equals(AUTO_START_PROP))
+            {
+                try
+                {
+                    startLevel = Integer.parseInt(key.substring(key.lastIndexOf('.') + 1));
+                }
+                catch (NumberFormatException ex)
+                {
+                    System.err.println("Invalid property: " + key);
+                }
+            }
+
+            // Parse and install the bundles associated with the key.
+            StringTokenizer st = new StringTokenizer((String) m_configMap.get(key), "\" ", true);
+            for (String location = nextLocation(st); location != null; location = nextLocation(st))
+            {
+                try
+                {
+                    Bundle b = context.installBundle(location, null);
+                    sl.setBundleStartLevel(b, startLevel);
+                }
+                catch (Exception ex)
+                {
+                    System.err.println("Auto-properties install: " + ex);
+                }
+            }
+        }
+
+        // Now loop through the auto-start bundles and start them.
+        for (Iterator i = m_configMap.keySet().iterator(); i.hasNext(); )
+        {
+            String key = (String) i.next();
+            if (key.startsWith(AUTO_START_PROP))
+            {
+                StringTokenizer st = new StringTokenizer((String) m_configMap.get(key), "\" ", true);
+                for (String location = nextLocation(st); location != null; location = nextLocation(st))
+                {
+                    // Installing twice just returns the same bundle.
+                    try
+                    {
+                        Bundle b = context.installBundle(location, null);
+                        if (b != null)
+                        {
+                            b.start();
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        System.err.println("Auto-properties start: " + ex);
+                    }
+                }
+            }
+        }
+    }
+
+    private static String nextLocation(StringTokenizer st)
+    {
+        String retVal = null;
+
+        if (st.countTokens() > 0)
+        {
+            String tokenList = "\" ";
+            StringBuffer tokBuf = new StringBuffer(10);
+            String tok = null;
+            boolean inQuote = false;
+            boolean tokStarted = false;
+            boolean exit = false;
+            while ((st.hasMoreTokens()) && (!exit))
+            {
+                tok = st.nextToken(tokenList);
+                if (tok.equals("\""))
+                {
+                    inQuote = ! inQuote;
+                    if (inQuote)
+                    {
+                        tokenList = "\"";
+                    }
+                    else
+                    {
+                        tokenList = "\" ";
+                    }
+
+                }
+                else if (tok.equals(" "))
+                {
+                    if (tokStarted)
+                    {
+                        retVal = tokBuf.toString();
+                        tokStarted=false;
+                        tokBuf = new StringBuffer(10);
+                        exit = true;
+                    }
+                }
+                else
+                {
+                    tokStarted = true;
+                    tokBuf.append(tok.trim());
+                }
+            }
+
+            // Handle case where end of token stream and
+            // still got data
+            if ((!exit) && (tokStarted))
+            {
+                retVal = tokBuf.toString();
+            }
+        }
+
+        return retVal;
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/AutoActivator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/AutoActivator.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/Main.java
URL: http://svn.apache.org/viewvc/cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/Main.java?rev=690991&view=auto
==============================================================================
--- cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/Main.java (added)
+++ cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/Main.java Mon Sep  1 08:08:01 2008
@@ -0,0 +1,617 @@
+/*
+ * 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.felix.main;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+import org.apache.felix.framework.Felix;
+import org.apache.felix.framework.cache.BundleCache;
+import org.apache.felix.framework.util.StringMap;
+
+/**
+ * <p>
+ * This class is the default way to instantiate and execute the framework. It is not
+ * intended to be the only way to instantiate and execute the framework; rather, it is
+ * one example of how to do so. When embedding the framework in a host application,
+ * this class can serve as a simple guide of how to do so. It may even be
+ * worthwhile to reuse some of its property handling capabilities.
+ * </p>
+**/
+public class Main
+{
+    /**
+     * The property name used to specify an URL to the system
+     * property file.
+    **/
+    public static final String SYSTEM_PROPERTIES_PROP = "felix.system.properties";
+    /**
+     * The default name used for the system properties file.
+    **/
+    public static final String SYSTEM_PROPERTIES_FILE_VALUE = "system.properties";
+    /**
+     * The property name used to specify an URL to the configuration
+     * property file to be used for the created the framework instance.
+    **/
+    public static final String CONFIG_PROPERTIES_PROP = "felix.config.properties";
+    /**
+     * The default name used for the configuration properties file.
+    **/
+    public static final String CONFIG_PROPERTIES_FILE_VALUE = "config.properties";
+    /**
+     * The default name used for the default configuration properties file.
+    **/
+    public static final String DEFAULT_PROPERTIES_FILE_VALUE = "default.properties";
+
+    private static Felix m_felix = null;
+
+    /**
+     * <p>
+     * This method performs the main task of constructing an framework instance
+     * and starting its execution. The following functions are performed
+     * when invoked:
+     * </p>
+     * <ol>
+     *   <li><i><b>Read the system properties file.<b></i> This is a file
+     *       containing properties to be pushed into <tt>System.setProperty()</tt>
+     *       before starting the framework. This mechanism is mainly shorthand
+     *       for people starting the framework from the command line to avoid having
+     *       to specify a bunch of <tt>-D</tt> system property definitions.
+     *       The only properties defined in this file that will impact the framework's
+     *       behavior are the those concerning setting HTTP proxies, such as
+     *       <tt>http.proxyHost</tt>, <tt>http.proxyPort</tt>, and
+     *       <tt>http.proxyAuth</tt>. Generally speaking, the framework does
+     *       not use system properties at all.
+     *   </li>
+     *   <li><i><b>Perform system property variable substitution on system
+     *       properties.</b></i> Any system properties in the system property
+     *       file whose value adheres to <tt>${&lt;system-prop-name&gt;}</tt>
+     *       syntax will have their value substituted with the appropriate
+     *       system property value.
+     *   </li>
+     *   <li><i><b>Read the framework's configuration property file.</b></i> This is
+     *       a file containing properties used to configure the framework
+     *       instance and to pass configuration information into
+     *       bundles installed into the framework instance. The configuration
+     *       property file is called <tt>config.properties</tt> by default
+     *       and is located in the <tt>conf/</tt> directory of the Felix
+     *       installation directory, which is the parent directory of the
+     *       directory containing the <tt>felix.jar</tt> file. It is possible
+     *       to use a different location for the property file by specifying
+     *       the desired URL using the <tt>felix.config.properties</tt>
+     *       system property; this should be set using the <tt>-D</tt> syntax
+     *       when executing the JVM. If the <tt>config.properties</tt> file
+     *       cannot be found, then the bare-bones <tt>default.properties</tt>
+     *       configuration file will be used to set the configuration properties;
+     *       this file is embedded in the launcher JAR file. Refer to the
+     *       <a href="Felix.html#Felix(java.util.Map, java.util.List)">
+     *       <tt>Felix</tt></a> constructor documentation for more
+     *       information on the framework configuration options.
+     *   </li>
+     *   <li><i><b>Perform system property variable substitution on configuration
+     *       properties.</b></i> Any configuration properties whose value adheres to
+     *       <tt>${&lt;system-prop-name&gt;}</tt> syntax will have their value
+     *       substituted with the appropriate system property value.
+     *   </li>
+     *   <li><i><b>Ensure the default bundle cache has sufficient information to
+     *       initialize.</b></i> The default implementation of the bundle cache
+     *       requires either a profile name or a profile directory in order to
+     *       start. The configuration properties are checked for at least one
+     *       of the <tt>felix.cache.profile</tt> or <tt>felix.cache.profiledir</tt>
+     *       properties. If neither is found, the user is asked to supply a profile
+     *       name that is added to the configuration property set. See the
+     *       <a href="cache/DefaultBundleCache.html"><tt>DefaultBundleCache</tt></a>
+     *       documentation for more details its configuration options.
+     *   </li>
+     *   <li><i><b>Creates and starts a framework instance.</b></i> A
+     *       case insensitive
+     *       <a href="util/StringMap.html"><tt>StringMap</tt></a>
+     *       is created for the configuration property file and is passed
+     *       into the framework.
+     *   </li>
+     * </ol>
+     * <p>
+     * It should be noted that simply starting an instance of the framework is not enough
+     * to create an interactive session with it. It is necessary to install
+     * and start bundles that provide a some means to interact with the framework;
+     * this is generally done by specifying an "auto-start" property in the
+     * framework configuration property file. If no bundles providing a means to
+     * interact with the framework are installed or if the configuration property
+     * file cannot be found, the framework will appear to be hung or deadlocked.
+     * This is not the case, it is executing correctly, there is just no way to
+     * interact with it. The default launcher provides two configuration properties
+     * to help you automatically install and/or start bundles, which are:
+     * </p>
+     * <ul>
+     *   <li><tt>felix.auto.install.&lt;n&gt;</tt> - Space-delimited list of
+     *       bundle URLs to automatically install into start level <tt>n</tt> when
+     *       the framework is started. Append a specific start level to this
+     *       property name to assign the bundles' start level
+     *       (e.g., <tt>felix.auto.install.2</tt>); otherwise, bundles are
+     *       installed into the default bundle start level.
+     *   </li>
+     *   <li><tt>felix.auto.start.&lt;n&gt;</tt> - Space-delimited list of
+     *       bundle URLs to automatically install and start into start level
+     *       <tt>n</tt> when the framework is started. Append a
+     *       specific start level to this property name to assign the
+     *       bundles' start level(e.g., <tt>felix.auto.start.2</tt>); otherwise,
+     *       bundles are installed into the default bundle start level.
+     *   </li>
+     * </ul>
+     * <p>
+     * These properties should be specified in the <tt>config.properties</tt>
+     * so that they can be processed by the launcher during the framework
+     * startup process.
+     * </p>
+     * @param argv An array of arguments, all of which are ignored.
+     * @throws Exception If an error occurs.
+    **/
+
+    public static void main(String[] argv) throws Exception
+    {
+        // Load system properties.
+        Main.loadSystemProperties();
+
+        // Read configuration properties.
+        Properties configProps = Main.loadConfigProperties();
+
+        // Copy framework properties from the system properties.
+        Main.copySystemProperties(configProps);
+
+        // See if the profile name property was specified.
+        String profileName = configProps.getProperty(BundleCache.CACHE_PROFILE_PROP);
+
+        // See if the profile directory property was specified.
+        String profileDirName = configProps.getProperty(BundleCache.CACHE_PROFILE_DIR_PROP);
+
+        // Print welcome banner.
+        System.out.println("\nWelcome to Felix.");
+        System.out.println("=================\n");
+
+        // If no profile or profile directory is specified in the
+        // properties, then ask for a profile name.
+        if ((profileName == null) && (profileDirName == null))
+        {
+            System.out.print("Enter profile name: ");
+            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+            try
+            {
+                profileName = in.readLine();
+            }
+            catch (IOException ex)
+            {
+                System.err.println("Could not read input.");
+                System.exit(-1);
+            }
+            System.out.println("");
+            if (profileName.length() != 0)
+            {
+                configProps.setProperty(BundleCache.CACHE_PROFILE_PROP, profileName);
+            }
+        }
+
+        // A profile directory or name must be specified.
+        if ((profileDirName == null) && (profileName.length() == 0))
+        {
+            System.err.println("You must specify a profile name or directory.");
+            System.exit(-1);
+        }
+
+        try
+        {
+            // Create a list for custom framework activators and
+            // add an instance of the auto-activator it for processing
+            // auto-install and auto-start properties.
+            List list = new ArrayList();
+            list.add(new AutoActivator(configProps));
+            // Create a case-insensitive property map.
+            Map configMap = new StringMap(configProps, false);
+            // Create an instance of the framework.
+            m_felix = new Felix(configMap, list);
+            m_felix.start();
+        }
+        catch (Exception ex)
+        {
+            System.err.println("Could not create framework: " + ex);
+            ex.printStackTrace();
+            System.exit(-1);
+        }
+    }
+
+    /**
+     * <p>
+     * Loads the properties in the system property file associated with the
+     * framework installation into <tt>System.setProperty()</tt>. These properties
+     * are not directly used by the framework in anyway. By default, the system
+     * property file is located in the <tt>conf/</tt> directory of the Felix
+     * installation directory and is called "<tt>system.properties</tt>". The
+     * installation directory of Felix is assumed to be the parent directory of
+     * the <tt>felix.jar</tt> file as found on the system class path property.
+     * The precise file from which to load system properties can be set by
+     * initializing the "<tt>felix.system.properties</tt>" system property to an
+     * arbitrary URL.
+     * </p>
+    **/
+    public static void loadSystemProperties()
+    {
+        // The system properties file is either specified by a system
+        // property or it is in the same directory as the Felix JAR file.
+        // Try to load it from one of these places.
+
+        // See if the property URL was specified as a property.
+        URL propURL = null;
+        String custom = System.getProperty(SYSTEM_PROPERTIES_PROP);
+        if (custom != null)
+        {
+            try
+            {
+                propURL = new URL(custom);
+            }
+            catch (MalformedURLException ex)
+            {
+                System.err.print("Main: " + ex);
+                return;
+            }
+        }
+        else
+        {
+            // Determine where the configuration directory is by figuring
+            // out where felix.jar is located on the system class path.
+            File confDir = null;
+            String classpath = System.getProperty("java.class.path");
+            int index = classpath.toLowerCase().indexOf("felix.jar");
+            int start = classpath.lastIndexOf(File.pathSeparator, index) + 1;
+            if (index >= start)
+            {
+                // Get the path of the felix.jar file.
+                String jarLocation = classpath.substring(start, index);
+                // Calculate the conf directory based on the parent
+                // directory of the felix.jar directory.
+                confDir = new File(
+                    new File(new File(jarLocation).getAbsolutePath()).getParent(),
+                    "conf");
+            }
+            else
+            {
+                // Can't figure it out so use the current directory as default.
+                confDir = new File(System.getProperty("user.dir"));
+            }
+
+            try
+            {
+                propURL = new File(confDir, SYSTEM_PROPERTIES_FILE_VALUE).toURL();
+            }
+            catch (MalformedURLException ex)
+            {
+                System.err.print("Main: " + ex);
+                return;
+            }
+        }
+
+        // Read the properties file.
+        Properties props = new Properties();
+        InputStream is = null;
+        try
+        {
+            is = propURL.openConnection().getInputStream();
+            props.load(is);
+            is.close();
+        }
+        catch (FileNotFoundException ex)
+        {
+            // Ignore file not found.
+        }
+        catch (Exception ex)
+        {
+            System.err.println(
+                "Main: Error loading system properties from " + propURL);
+            System.err.println("Main: " + ex);
+            try
+            {
+                if (is != null) is.close();
+            }
+            catch (IOException ex2)
+            {
+                // Nothing we can do.
+            }
+            return;
+        }
+
+        // Perform variable substitution on specified properties.
+        for (Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+        {
+            String name = (String) e.nextElement();
+            System.setProperty(name,
+                substVars(props.getProperty(name), name, null, null));
+        }
+    }
+
+    /**
+     * <p>
+     * Loads the configuration properties in the configuration property file
+     * associated with the framework installation; these properties
+     * are accessible to the framework and to bundles and are intended
+     * for configuration purposes. By default, the configuration property
+     * file is located in the <tt>conf/</tt> directory of the Felix
+     * installation directory and is called "<tt>config.properties</tt>".
+     * The installation directory of Felix is assumed to be the parent
+     * directory of the <tt>felix.jar</tt> file as found on the system class
+     * path property. The precise file from which to load configuration
+     * properties can be set by initializing the "<tt>felix.config.properties</tt>"
+     * system property to an arbitrary URL.
+     * </p>
+     * @return A <tt>Properties</tt> instance or <tt>null</tt> if there was an error.
+    **/
+    public static Properties loadConfigProperties()
+    {
+        // The config properties file is either specified by a system
+        // property or it is in the conf/ directory of the Felix
+        // installation directory.  Try to load it from one of these
+        // places.
+
+        // See if the property URL was specified as a property.
+        URL propURL = null;
+        String custom = System.getProperty(CONFIG_PROPERTIES_PROP);
+        if (custom != null)
+        {
+            try
+            {
+                propURL = new URL(custom);
+            }
+            catch (MalformedURLException ex)
+            {
+                System.err.print("Main: " + ex);
+                return null;
+            }
+        }
+        else
+        {
+            // Determine where the configuration directory is by figuring
+            // out where felix.jar is located on the system class path.
+            File confDir = null;
+            String classpath = System.getProperty("java.class.path");
+            int index = classpath.toLowerCase().indexOf("felix.jar");
+            int start = classpath.lastIndexOf(File.pathSeparator, index) + 1;
+            if (index >= start)
+            {
+                // Get the path of the felix.jar file.
+                String jarLocation = classpath.substring(start, index);
+                // Calculate the conf directory based on the parent
+                // directory of the felix.jar directory.
+                confDir = new File(
+                    new File(new File(jarLocation).getAbsolutePath()).getParent(),
+                    "conf");
+            }
+            else
+            {
+                // Can't figure it out so use the current directory as default.
+                confDir = new File(System.getProperty("user.dir"));
+            }
+
+            try
+            {
+                propURL = new File(confDir, CONFIG_PROPERTIES_FILE_VALUE).toURL();
+            }
+            catch (MalformedURLException ex)
+            {
+                System.err.print("Main: " + ex);
+                return null;
+            }
+        }
+
+        // Read the properties file.
+        Properties props = new Properties();
+        InputStream is = null;
+        try
+        {
+            // Try to load config.properties.
+            is = propURL.openConnection().getInputStream();
+            props.load(is);
+            is.close();
+        }
+        catch (Exception ex)
+        {
+            // Try to close input stream if we have one.
+            try
+            {
+                if (is != null) is.close();
+            }
+            catch (IOException ex2)
+            {
+                // Nothing we can do.
+            }
+
+            // If we cannot the configuration properties for any reason, then just
+            // attempt to load resource default.properties instead.
+            propURL = Main.class.getClassLoader().getResource(DEFAULT_PROPERTIES_FILE_VALUE);
+            try
+            {
+                is = propURL.openConnection().getInputStream();
+                props.load(is);
+                is.close();
+                System.err.println("\nUsing default configuration properties.");
+            }
+            catch (Exception ex2)
+            {
+                // Try to close input stream if we have one.
+                try
+                {
+                    if (is != null) is.close();
+                }
+                catch (IOException ex3)
+                {
+                    // Nothing we can do.
+                }
+                System.err.println("\nUnable to load any configuration properties.");
+                return null;
+            }
+        }
+
+        // Perform variable substitution for system properties.
+        for (Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+        {
+            String name = (String) e.nextElement();
+            props.setProperty(name,
+                substVars(props.getProperty(name), name, null, props));
+        }
+
+        return props;
+    }
+
+    public static void copySystemProperties(Properties configProps)
+    {
+        for (Enumeration e = System.getProperties().propertyNames();
+             e.hasMoreElements(); )
+        {
+            String key = (String) e.nextElement();
+            if (key.startsWith("felix.") ||
+                key.equals("org.osgi.framework.system.packages") ||
+                key.equals("org.osgi.framework.bootdelegation"))
+            {
+                configProps.setProperty(key, System.getProperty(key));
+            }
+        }
+    }
+
+    private static final String DELIM_START = "${";
+    private static final String DELIM_STOP  = "}";
+
+    /**
+     * <p>
+     * This method performs property variable substitution on the
+     * specified value. If the specified value contains the syntax
+     * <tt>${&lt;prop-name&gt;}</tt>, where <tt>&lt;prop-name&gt;</tt>
+     * refers to either a configuration property or a system property,
+     * then the corresponding property value is substituted for the variable
+     * placeholder. Multiple variable placeholders may exist in the
+     * specified value as well as nested variable placeholders, which
+     * are substituted from inner most to outer most. Configuration
+     * properties override system properties.
+     * </p>
+     * @param val The string on which to perform property substitution.
+     * @param currentKey The key of the property being evaluated used to
+     *        detect cycles.
+     * @param cycleMap Map of variable references used to detect nested cycles.
+     * @param configProps Set of configuration properties.
+     * @return The value of the specified string after system property substitution.
+     * @throws IllegalArgumentException If there was a syntax error in the
+     *         property placeholder syntax or a recursive variable reference.
+    **/
+    public static String substVars(String val, String currentKey,
+        Map cycleMap, Properties configProps)
+        throws IllegalArgumentException
+    {
+        // If there is currently no cycle map, then create
+        // one for detecting cycles for this invocation.
+        if (cycleMap == null)
+        {
+            cycleMap = new HashMap();
+        }
+
+        // Put the current key in the cycle map.
+        cycleMap.put(currentKey, currentKey);
+
+        // Assume we have a value that is something like:
+        // "leading ${foo.${bar}} middle ${baz} trailing"
+
+        // Find the first ending '}' variable delimiter, which
+        // will correspond to the first deepest nested variable
+        // placeholder.
+        int stopDelim = val.indexOf(DELIM_STOP);
+
+        // Find the matching starting "${" variable delimiter
+        // by looping until we find a start delimiter that is
+        // greater than the stop delimiter we have found.
+        int startDelim = val.indexOf(DELIM_START);
+        while (stopDelim >= 0)
+        {
+            int idx = val.indexOf(DELIM_START, startDelim + DELIM_START.length());
+            if ((idx < 0) || (idx > stopDelim))
+            {
+                break;
+            }
+            else if (idx < stopDelim)
+            {
+                startDelim = idx;
+            }
+        }
+
+        // If we do not have a start or stop delimiter, then just
+        // return the existing value.
+        if ((startDelim < 0) && (stopDelim < 0))
+        {
+            return val;
+        }
+        // At this point, we found a stop delimiter without a start,
+        // so throw an exception.
+        else if (((startDelim < 0) || (startDelim > stopDelim))
+            && (stopDelim >= 0))
+        {
+            throw new IllegalArgumentException(
+                "stop delimiter with no start delimiter: "
+                + val);
+        }
+
+        // At this point, we have found a variable placeholder so
+        // we must perform a variable substitution on it.
+        // Using the start and stop delimiter indices, extract
+        // the first, deepest nested variable placeholder.
+        String variable =
+            val.substring(startDelim + DELIM_START.length(), stopDelim);
+
+        // Verify that this is not a recursive variable reference.
+        if (cycleMap.get(variable) != null)
+        {
+            throw new IllegalArgumentException(
+                "recursive variable reference: " + variable);
+        }
+
+        // Get the value of the deepest nested variable placeholder.
+        // Try to configuration properties first.
+        String substValue = (configProps != null)
+            ? configProps.getProperty(variable, null)
+            : null;
+        if (substValue == null)
+        {
+            // Ignore unknown property values.
+            substValue = System.getProperty(variable, "");
+        }
+
+        // Remove the found variable from the cycle map, since
+        // it may appear more than once in the value and we don't
+        // want such situations to appear as a recursive reference.
+        cycleMap.remove(variable);
+
+        // Append the leading characters, the substituted value of
+        // the variable, and the trailing characters to get the new
+        // value.
+        val = val.substring(0, startDelim)
+            + substValue
+            + val.substring(stopDelim + DELIM_STOP.length(), val.length());
+
+        // Now perform substitution again, since there could still
+        // be substitutions to make.
+        val = substVars(val, currentKey, cycleMap, configProps);
+
+        // Return the value.
+        return val;
+    }
+}
\ No newline at end of file

Propchange: cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/Main.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/sandbox/dosgi/felix/main/src/main/java/org/apache/felix/main/Main.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date



Mime
View raw message