Return-Path: Delivered-To: apmail-felix-commits-archive@www.apache.org Received: (qmail 15121 invoked from network); 4 Aug 2008 15:02:32 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 4 Aug 2008 15:02:32 -0000 Received: (qmail 36137 invoked by uid 500); 4 Aug 2008 15:02:31 -0000 Delivered-To: apmail-felix-commits-archive@felix.apache.org Received: (qmail 36112 invoked by uid 500); 4 Aug 2008 15:02:31 -0000 Mailing-List: contact commits-help@felix.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@felix.apache.org Delivered-To: mailing list commits@felix.apache.org Received: (qmail 36103 invoked by uid 99); 4 Aug 2008 15:02:31 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 04 Aug 2008 08:02:31 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 04 Aug 2008 15:01:34 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 52D4E2388876; Mon, 4 Aug 2008 08:01:31 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r682415 - in /felix/trunk/deploymentadmin: ./ autoconf/ autoconf/src/ autoconf/src/main/ autoconf/src/main/java/ autoconf/src/main/java/org/ autoconf/src/main/java/org/apache/ autoconf/src/main/java/org/apache/felix/ autoconf/src/main/java/... Date: Mon, 04 Aug 2008 15:01:30 -0000 To: commits@felix.apache.org From: christian@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080804150131.52D4E2388876@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: christian Date: Mon Aug 4 08:01:29 2008 New Revision: 682415 URL: http://svn.apache.org/viewvc?rev=682415&view=rev Log: FELIX-454 Initial version of the Autoconf Resource Processor Added: felix/trunk/deploymentadmin/autoconf/ felix/trunk/deploymentadmin/autoconf/LICENSE felix/trunk/deploymentadmin/autoconf/NOTICE felix/trunk/deploymentadmin/autoconf/pom.xml felix/trunk/deploymentadmin/autoconf/src/ felix/trunk/deploymentadmin/autoconf/src/main/ felix/trunk/deploymentadmin/autoconf/src/main/java/ felix/trunk/deploymentadmin/autoconf/src/main/java/org/ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AttributeDefinitionImpl.java felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/ObjectClassDefinitionImpl.java felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java Modified: felix/trunk/deploymentadmin/pom.xml Added: felix/trunk/deploymentadmin/autoconf/LICENSE URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/LICENSE?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/LICENSE (added) +++ felix/trunk/deploymentadmin/autoconf/LICENSE Mon Aug 4 08:01:29 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. Added: felix/trunk/deploymentadmin/autoconf/NOTICE URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/NOTICE?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/NOTICE (added) +++ felix/trunk/deploymentadmin/autoconf/NOTICE Mon Aug 4 08:01:29 2008 @@ -0,0 +1,10 @@ +Apache Felix Framework +Copyright 2006 The Apache Software Foundation + +This product includes software developed at +The Apache Software Foundation (http://www.apache.org/). + +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. Added: felix/trunk/deploymentadmin/autoconf/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/pom.xml?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/pom.xml (added) +++ felix/trunk/deploymentadmin/autoconf/pom.xml Mon Aug 4 08:01:29 2008 @@ -0,0 +1,83 @@ + + + + + org.apache.felix + felix + 1.0.2 + ../../pom/pom.xml + + 4.0.0 + bundle + Apache Felix AutoConf Resource Processor + 0.1.0-SNAPSHOT + org.apache.felix.deployment.rp.autoconf + + + ${pom.groupId} + org.osgi.core + 1.1.0-SNAPSHOT + provided + + + ${pom.groupId} + org.osgi.compendium + 1.1.0-SNAPSHOT + + + ${pom.groupId} + org.apache.felix.dependencymanager + 1.1.0-SNAPSHOT + provided + + + ${pom.groupId} + org.apache.felix.deploymentadmin + 0.9.0-SNAPSHOT + + + ${pom.groupId} + org.apache.felix.metatype + 1.0.1-SNAPSHOT + + + + + + org.apache.felix + maven-bundle-plugin + 1.4.0 + true + + + org.apache.felix.deployment.rp.autoconf + org.apache.felix.deployment.rp.autoconf.Activator + Apache Felix AutoConf Resource Processor + A customizer bundle that publishes a Resource Processor service that processes configuration resources shipped in a Deployment Package. + Apache Software Foundation + org.apache.felix.deployment.rp.autoconf, org.apache.felix.metatype, org.apache.felix.metatype.internal.l10n, org.apache.felix.metatype.internal, org.kxml2.io;-split-package:=merge-first, org.xmlpull.v1;-split-package:=merge-first, org.osgi.service.metatype;-split-package:=merge-first + org.osgi.service.deploymentadmin.spi;version="1.0" + true + + + + + + Added: felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java (added) +++ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/Activator.java Mon Aug 4 08:01:29 2008 @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.felix.deployment.rp.autoconf; + +import java.util.Dictionary; +import java.util.Properties; + +import org.apache.felix.dependencymanager.DependencyActivatorBase; +import org.apache.felix.dependencymanager.DependencyManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.deploymentadmin.spi.ResourceProcessor; +import org.osgi.service.log.LogService; +import org.osgi.service.metatype.MetaTypeService; + +/** + * Bundle activator for the AutoConf Resource Processor Customizer bundle + */ +public class Activator extends DependencyActivatorBase { + + public void init(BundleContext context, DependencyManager manager) throws Exception { + Dictionary properties = new Properties(); + properties.put(Constants.SERVICE_PID, "org.osgi.deployment.rp.autoconf"); + + manager.add(createService() + .setInterface(ResourceProcessor.class.getName(), properties) + .setImplementation(AutoConfResourceProcessor.class) + .add(createServiceDependency() + .setService(ConfigurationAdmin.class) + .setRequired(true)) + .add(createServiceDependency() + .setService(MetaTypeService.class) + .setRequired(false)) + .add(createServiceDependency() + .setService(LogService.class) + .setRequired(false))); + } + + public void destroy(BundleContext context, DependencyManager manager) throws Exception { + // do nothing + } +} \ No newline at end of file Added: felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AttributeDefinitionImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AttributeDefinitionImpl.java?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AttributeDefinitionImpl.java (added) +++ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AttributeDefinitionImpl.java Mon Aug 4 08:01:29 2008 @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.felix.deployment.rp.autoconf; + +import org.apache.felix.metatype.AD; +import org.osgi.service.metatype.AttributeDefinition; + +public class AttributeDefinitionImpl implements AttributeDefinition { + + private final AD m_ad; + + public AttributeDefinitionImpl(AD ad) { + m_ad = ad; + } + + public int getCardinality() { + return m_ad.getCardinality(); + } + + public String[] getDefaultValue() { + return m_ad.getDefaultValue(); + } + + public String getDescription() { + return m_ad.getDescription(); + } + + public String getID() { + return m_ad.getID(); + } + + public String getName() { + return m_ad.getName(); + } + + public String[] getOptionLabels() { + return m_ad.getOptionLabels(); + } + + public String[] getOptionValues() { + return m_ad.getOptionValues(); + } + + public int getType() { + return m_ad.getType(); + } + + public String validate(String value) { + return m_ad.validate(value); + } + +} Added: felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java (added) +++ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResource.java Mon Aug 4 08:01:29 2008 @@ -0,0 +1,105 @@ +/* + * 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.deployment.rp.autoconf; + +import java.io.Serializable; +import java.util.Dictionary; + +public class AutoConfResource implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String m_pid; + private final String m_factoryPid; + private final Dictionary m_properties; + private final String m_bundleLoc; + private final boolean m_merge; + private final String m_name; + + private String m_alias = null; + + public AutoConfResource(String name, String pid, String factoryPid, String bundleLocation, boolean merge, Dictionary properties) { + m_name = name; + m_pid = pid; + m_factoryPid = (factoryPid == null) ? "" : factoryPid; + m_bundleLoc = bundleLocation; + m_merge = merge; + m_properties = properties; + } + + public String getName() { + return m_name; + } + + public String getPid() { + return m_pid; + } + + /** + * Returns empty string if this configuration is not a factory configuration, otherwise the factory + * PID is returned. + * + * @return Empty string if this is not a factory configuration resource, else the factory PID is returned. + */ + public String getFactoryPid() { + return m_factoryPid; + } + + public Dictionary getProperties() { + return m_properties; + } + + public String getBundleLocation() { + return m_bundleLoc; + } + + public boolean isMerge() { + return m_merge; + } + + public boolean isFactoryConfig() { + return !(m_factoryPid == null || "".equals(m_factoryPid)); + } + + public void setGeneratedPid(String alias) { + m_alias = alias; + } + + public String getGeneratedPid() { + if (m_alias == null) { + throw new IllegalStateException("Must set an alias first."); + } + return m_alias; + } + + /** + * Determine if the specified AutoConfResource is meant to be used for the same Configuration as this object. + * + * @param resource The AutoConfResource to compare with. + * @return Returns true if the two resources are meant to be used for the same Configuration object, false otherwise. + */ + public boolean equalsTargetConfiguration(AutoConfResource resource) { + if (isFactoryConfig()) { + return m_pid.equals(resource.getPid()) && m_factoryPid.equals(resource.getFactoryPid()); + } + else { + return m_pid.equals(resource.getPid()); + } + } +} Added: felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java (added) +++ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/AutoConfResourceProcessor.java Mon Aug 4 08:01:29 2008 @@ -0,0 +1,531 @@ +/* + * 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.deployment.rp.autoconf; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import org.apache.felix.metatype.Attribute; +import org.apache.felix.metatype.Designate; +import org.apache.felix.metatype.MetaData; +import org.apache.felix.metatype.MetaDataReader; +import org.apache.felix.metatype.OCD; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.deploymentadmin.spi.DeploymentSession; +import org.osgi.service.deploymentadmin.spi.ResourceProcessor; +import org.osgi.service.deploymentadmin.spi.ResourceProcessorException; +import org.osgi.service.log.LogService; +import org.osgi.service.metatype.AttributeDefinition; +import org.osgi.service.metatype.MetaTypeInformation; +import org.osgi.service.metatype.MetaTypeService; +import org.osgi.service.metatype.ObjectClassDefinition; +import org.xmlpull.v1.XmlPullParserException; + +public class AutoConfResourceProcessor implements ResourceProcessor { + + private static final String LOCATION_PREFIX = "osgi-dp:"; + + private volatile LogService m_log; // injected by dependency manager + private volatile ConfigurationAdmin m_configAdmin; // injected by dependency manager + private volatile MetaTypeService m_metaService; // injected by dependency manager + private volatile BundleContext m_bc; // injected by dependency manager + + private DeploymentSession m_session = null; + private Map m_toBeInstalled = new HashMap(); // Map> + private Map m_toBeDeleted = new HashMap(); + + private PersistencyManager m_persistencyManager; + + public void start() throws IOException { + File root = m_bc.getDataFile(""); + if (root == null) { + throw new IOException("No file system support"); + } + m_persistencyManager = new PersistencyManager(root); + } + + public void begin(DeploymentSession session) { + m_session = session; + } + + public void process(String name, InputStream stream) throws ResourceProcessorException { + + // initial validation + if (m_session == null) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can not process resource without a Deployment Session"); + } + MetaDataReader reader = new MetaDataReader(); + MetaData data = null; + try { + data = reader.parse(stream); + } catch (IOException e) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Unable to process resource.", e); + } catch (XmlPullParserException e) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Supplied configuration is not conform the metatype xml specification.", e); + } + if (data == null) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Supplied configuration is not conform the metatype xml specification."); + } + + // process resources + Map designates = data.getDesignates(); + Map localOcds = data.getObjectClassDefinitions(); + Iterator i = designates.keySet().iterator(); + while (i.hasNext()) { + Designate designate = (Designate) designates.get(i.next()); + + // determine OCD + ObjectClassDefinition ocd = null; + String ocdRef = designate.getObject().getOcdRef(); + OCD localOcd = (OCD) localOcds.get(ocdRef); + // ask meta type service for matching OCD if no local OCD has been defined + ocd = (localOcd != null) ? new ObjectClassDefinitionImpl(localOcd) : getMetaTypeOCD(data, designate); + if (ocd == null) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "No Object Class Definition found with id=" + ocdRef); + } + + // determine configuration data based on the values and their type definition + Dictionary dict = getProperties(designate, ocd); + if (dict == null) { + // designate does not match it's definition, but was marked optional, ignore it + continue; + } + + // add to session data + if (!m_toBeInstalled.containsKey(name)) { + m_toBeInstalled.put(name, new ArrayList()); + } + List resources = (List) m_toBeInstalled.get(name); + resources.add(new AutoConfResource(name, designate.getPid(), designate.getFactoryPid(), designate.getBundleLocation(), designate.isMerge(), dict)); + } + } + + public void dropped(String name) throws ResourceProcessorException { + if (m_session == null) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can not process resource without a Deployment Session"); + } + try { + List resources = m_persistencyManager.load(name); + if (!m_toBeDeleted.containsKey(name)) { + m_toBeDeleted.put(name, new ArrayList()); + } + ((List) m_toBeDeleted.get(name)).addAll(resources); + } + catch (IOException ioe) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Unable to drop resource: " + name, ioe); + } + } + + public void dropAllResources() throws ResourceProcessorException { + if (m_session == null) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can not drop all resources without a Deployment Session"); + } + try { + Map loadAll = m_persistencyManager.loadAll(); + for (Iterator i = loadAll.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + dropped(name); + } + } + catch (IOException ioe) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Unable to drop all resources.", ioe); + } + + File basedir = m_bc.getDataFile(""); + if (basedir != null && basedir.isDirectory()) { + String[] files = basedir.list(); + for (int i = 0; i < files.length; i++) { + dropped(files[i]); + } + } + else { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Unable to drop resources, data area is not accessible"); + } + } + + public void prepare() throws ResourceProcessorException { + if (m_session == null) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Can not process resource without a Deployment Session"); + } + + try { + // delete dropped resources + for (Iterator i = m_toBeDeleted.keySet().iterator(); i.hasNext();) { + String name = (String) i.next(); + List resources = (List) m_toBeDeleted.get(name); + for (Iterator j = resources.iterator(); j.hasNext();) { + AutoConfResource resource = (AutoConfResource) j.next(); + if (resource.isFactoryConfig()) { + Configuration configuration = m_configAdmin.getConfiguration(resource.getGeneratedPid(), resource.getBundleLocation()); + configuration.delete(); + } else { + Configuration configuration = m_configAdmin.getConfiguration(resource.getPid(), resource.getBundleLocation()); + configuration.delete(); + } + } + m_persistencyManager.delete(name); + } + + // install new/updated resources + for (Iterator j = m_toBeInstalled.keySet().iterator(); j.hasNext();) { + String name = (String) j.next(); + List existingResources = null; + try { + existingResources = m_persistencyManager.load(name); + } catch (IOException ioe) { + throw new ResourceProcessorException(ResourceProcessorException.CODE_PREPARE, "Unable to read existing resources for resource " + name, ioe); + } + List resources = (List) m_toBeInstalled.get(name); + for (Iterator iterator = resources.iterator(); iterator.hasNext();) { + AutoConfResource resource = (AutoConfResource) iterator.next(); + + Dictionary properties = resource.getProperties(); + String bundleLocation = resource.getBundleLocation(); + Configuration configuration = null; + + // update configuration + if (resource.isFactoryConfig()) { + // check if this is an factory config instance update + for (Iterator i = existingResources.iterator(); i.hasNext();) { + AutoConfResource existingResource = (AutoConfResource) i.next(); + if (resource.equalsTargetConfiguration(existingResource)) { + // existing instance found + configuration = m_configAdmin.getConfiguration(existingResource.getGeneratedPid(), bundleLocation); + existingResources.remove(existingResource); + break; + } + } + if (configuration == null) { + // no existing instance, create new + configuration = m_configAdmin.createFactoryConfiguration(resource.getFactoryPid(), bundleLocation); + } + resource.setGeneratedPid(configuration.getPid()); + } + else { + for (Iterator i = existingResources.iterator(); i.hasNext();) { + AutoConfResource existingResource = (AutoConfResource) i.next(); + if (resource.getPid().equals(existingResource.getPid())) { + // existing resource found + existingResources.remove(existingResource); + break; + } + } + configuration = m_configAdmin.getConfiguration(resource.getPid(), bundleLocation); + if (!bundleLocation.equals(configuration.getBundleLocation())) { + // an existing configuration exists that is bound to a different location, which is not allowed + throw new ResourceProcessorException(ResourceProcessorException.CODE_PREPARE, "Existing configuration was not unbound and not bound to the specified bundlelocation"); + } + } + if (resource.isMerge()) { + Dictionary existingProperties = configuration.getProperties(); + if (existingProperties != null) { + Enumeration keys = existingProperties.keys(); + while (keys.hasMoreElements()) { + Object key = keys.nextElement(); + properties.put(key, existingProperties.get(key)); + } + } + } + configuration.update(properties); + } + + // remove existing configurations that were not in the new version of the resource + for (Iterator i = existingResources.iterator(); i.hasNext();) { + AutoConfResource existingResource = (AutoConfResource) i.next(); + Configuration configuration = null; + if (existingResource.isFactoryConfig()) { + configuration = m_configAdmin.getConfiguration(existingResource.getGeneratedPid(), existingResource.getBundleLocation()); + } else { + configuration = m_configAdmin.getConfiguration(existingResource.getPid(), existingResource.getBundleLocation()); + } + configuration.delete(); + } + m_persistencyManager.store(name, resources); + } + } + catch (IOException ioe) { + m_toBeInstalled.clear(); + throw new ResourceProcessorException(ResourceProcessorException.CODE_PREPARE, "Unable to prepare for commit for resource", ioe); + } + } + + public synchronized void commit() { + m_toBeInstalled.clear(); + m_toBeDeleted.clear(); + m_session = null; + } + + public void rollback() { + Set keys = m_toBeInstalled.keySet(); + for (Iterator i = keys.iterator(); i.hasNext();) { + List configs = (List) m_toBeInstalled.get(i.next()); + for (Iterator j = configs.iterator(); j.hasNext();) { + AutoConfResource resource = (AutoConfResource) j.next(); + String name = resource.getName(); + try { + dropped(name); + } catch (ResourceProcessorException e) { + m_log.log(LogService.LOG_ERROR, "Unable to roll back resource '" + name + "', reason: " + e.getMessage() + ", caused by: " + e.getCause().getMessage()); + } + break; + } + } + m_toBeInstalled.clear(); + m_session = null; + } + + public void cancel() { + rollback(); + m_session = null; + } + + /** + * Determines the actual configuration data based on the specified designate and object class definition + * + * @param designate The designate object containing the values for the properties + * @param ocd The object class definition + * @return A dictionary containing data as described in the designate and ocd objects, or null if the designate does not match it's + * definition and the designate was marked as optional. + * @throws ResourceProcessorException If the designate does not match the ocd and the designate is not marked as optional. + */ + private Dictionary getProperties(Designate designate, ObjectClassDefinition ocd) throws ResourceProcessorException { + Dictionary properties = new Hashtable(); + AttributeDefinition[] attributeDefs = ocd.getAttributeDefinitions(ObjectClassDefinition.ALL); + List attributes = designate.getObject().getAttributes(); + + for (Iterator i = attributes.iterator(); i.hasNext();) { + Attribute attribute = (Attribute) i.next(); + + String adRef = attribute.getAdRef(); + boolean found = false; + for(int j = 0; j < attributeDefs.length; j++) { + AttributeDefinition ad = attributeDefs[j]; + if (adRef.equals(ad.getID())) { + // found attribute definition + Object value = getValue(attribute, ad); + if (value == null) { + if (designate.isOptional()) { + properties = null; + break; + } + else { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Could not match attribute to it's definition: adref=" + adRef); + } + } + properties.put(adRef, value); + found = true; + break; + } + } + if (!found) { + if (designate.isOptional()) { + properties = null; + break; + } else { + throw new ResourceProcessorException(ResourceProcessorException.CODE_OTHER_ERROR, "Could not find attribute definition: adref=" + adRef); + } + } + } + + return properties; + } + + /** + * Determines the object class definition matching the specified designate. + * + * @param data The meta data containing 'local' object class definitions. + * @param designate The designate whose object class definition should be determined. + * @return + * @throws ResourceProcessorException + */ + private ObjectClassDefinition getMetaTypeOCD(MetaData data, Designate designate) throws ResourceProcessorException { + ObjectClassDefinition ocd = null; + String ocdRef = designate.getObject().getOcdRef(); + Bundle bundle = getBundle(designate.getBundleLocation(), isFactoryConfig(designate)); + if (bundle != null) { + MetaTypeInformation mti = m_metaService.getMetaTypeInformation(bundle); + if (mti != null) { + String pid = isFactoryConfig(designate) ? pid = designate.getFactoryPid() : designate.getPid(); + try { + ObjectClassDefinition tempOcd = mti.getObjectClassDefinition(pid, null); + // tempOcd will always have a value, if pid was not known IAE will be thrown + if (ocdRef.equals(tempOcd.getID())) { + ocd = tempOcd; + } + } + catch (IllegalArgumentException iae) { + // let null be returned + } + } + } + return ocd; + } + + private boolean isFactoryConfig(Designate designate) { + String factoryPid = designate.getFactoryPid(); + return (factoryPid != null || !"".equals(factoryPid)); + } + + private Bundle getBundle(String bundleLocation, boolean isFactory) throws ResourceProcessorException { + Bundle bundle = null; + if (!isFactory) { + // singleton configuration, no foreign bundles allowed, use source deployment package to find specified bundle + if (bundleLocation.startsWith(LOCATION_PREFIX)) { + bundle = m_session.getSourceDeploymentPackage().getBundle(bundleLocation.substring(LOCATION_PREFIX.length())); + } + } + else { + // factory configuration, foreign bundles allowed, use bundle context to find the specified bundle + Bundle[] bundles = m_bc.getBundles(); + for (int i = 0; i < bundles.length; i++) { + String location = bundles[i].getLocation(); + if (bundleLocation.equals(location)) { + bundle = bundles[i]; + break; + } + } + } + return bundle; + } + + /** + * Determines the value of an attribute based on an attribute definition + * + * @param attribute The attribute containing value(s) + * @param ad The attribute definition + * @return An Object reflecting what was specified in the attribute and it's definition or null if + * the value did not match it's definition. + */ + private Object getValue(Attribute attribute, AttributeDefinition ad) { + if (attribute == null || ad == null || !attribute.getAdRef().equals(ad.getID())) { + // wrong attribute or definition + return null; + } + String[] content = attribute.getContent(); + + // verify correct type of the value(s) + int type = ad.getType(); + Object[] typedContent = null; + try { + for (int i = 0; i < content.length; i++) { + String value = content[i]; + switch (type) { + case AttributeDefinition.BOOLEAN: + typedContent = (typedContent == null) ? new Boolean[content.length] : typedContent; + typedContent[i] = Boolean.valueOf(value); + break; + case AttributeDefinition.BYTE: + typedContent = (typedContent == null) ? new Byte[content.length] : typedContent; + typedContent[i] = Byte.valueOf(value); + break; + case AttributeDefinition.CHARACTER: + typedContent = (typedContent == null) ? new Character[content.length] : typedContent; + char[] charArray = value.toCharArray(); + if (charArray.length == 1) { + typedContent[i] = new Character(charArray[0]); + } + else { + return null; + } + break; + case AttributeDefinition.DOUBLE: + typedContent = (typedContent == null) ? new Double[content.length] : typedContent; + typedContent[i] = Double.valueOf(value); + break; + case AttributeDefinition.FLOAT: + typedContent = (typedContent == null) ? new Float[content.length] : typedContent; + typedContent[i] = Float.valueOf(value); + break; + case AttributeDefinition.INTEGER: + typedContent = (typedContent == null) ? new Integer[content.length] : typedContent; + typedContent[i] = Integer.valueOf(value); + break; + case AttributeDefinition.LONG: + typedContent = (typedContent == null) ? new Long[content.length] : typedContent; + typedContent[i] = Long.valueOf(value); + break; + case AttributeDefinition.SHORT: + typedContent = (typedContent == null) ? new Short[content.length] : typedContent; + typedContent[i] = Short.valueOf(value); + break; + case AttributeDefinition.STRING: + typedContent = (typedContent == null) ? new String[content.length] : typedContent; + typedContent[i] = value; + break; + default: + // unsupported type + return null; + } + } + } + catch (NumberFormatException nfe) { + return null; + } + + // verify cardinality of value(s) + int cardinality = ad.getCardinality(); + Object result = null; + if (cardinality == 0) { + if (typedContent.length == 1) { + result = typedContent[0]; + } + else { + result = null; + } + } + else if (cardinality == Integer.MIN_VALUE) { + result = new Vector(Arrays.asList(typedContent)); + } + else if (cardinality == Integer.MAX_VALUE) { + result = typedContent; + } + else if (cardinality < 0) { + if (typedContent.length == cardinality) { + result = new Vector(Arrays.asList(typedContent)); + } + else { + result = null; + } + } + else if (cardinality > 0) { + if (typedContent.length == cardinality) { + result = typedContent; + } + else { + result = null; + } + } + return result; + } +} Added: felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/ObjectClassDefinitionImpl.java URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/ObjectClassDefinitionImpl.java?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/ObjectClassDefinitionImpl.java (added) +++ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/ObjectClassDefinitionImpl.java Mon Aug 4 08:01:29 2008 @@ -0,0 +1,83 @@ +/* + * 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.deployment.rp.autoconf; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.felix.metatype.AD; +import org.apache.felix.metatype.OCD; +import org.osgi.service.metatype.AttributeDefinition; +import org.osgi.service.metatype.ObjectClassDefinition; + +public class ObjectClassDefinitionImpl implements ObjectClassDefinition { + + private final OCD m_ocd; + + public ObjectClassDefinitionImpl(OCD ocd) { + m_ocd = ocd; + } + + public AttributeDefinition[] getAttributeDefinitions(int filter) { + if (m_ocd.getAttributeDefinitions() == null) { + return null; + } + if (filter != ObjectClassDefinition.OPTIONAL && filter != ObjectClassDefinition.REQUIRED && filter != ObjectClassDefinition.ALL) { + return null; + } + + List result = new ArrayList(); + for (Iterator i = m_ocd.getAttributeDefinitions().values().iterator(); i.hasNext();) { + AD ad = (AD) i.next(); + if (filter != ObjectClassDefinition.ALL) { + if (ad.isRequired() && filter == ObjectClassDefinition.REQUIRED) { + result.add(new AttributeDefinitionImpl(ad)); + } + else if (!ad.isRequired() && filter == ObjectClassDefinition.OPTIONAL) { + result.add(new AttributeDefinitionImpl(ad)); + } + } else { + result.add(new AttributeDefinitionImpl(ad)); + } + } + + return (AttributeDefinition[]) result.toArray(new AttributeDefinition[result.size()]); + } + + public InputStream getIcon(int size) throws IOException { + // TODO Auto-generated method stub + return null; + } + + public String getDescription() { + return m_ocd.getDescription(); + } + + public String getID() { + return m_ocd.getID(); + } + + public String getName() { + return m_ocd.getName(); + } + +} Added: felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java?rev=682415&view=auto ============================================================================== --- felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java (added) +++ felix/trunk/deploymentadmin/autoconf/src/main/java/org/apache/felix/deployment/rp/autoconf/PersistencyManager.java Mon Aug 4 08:01:29 2008 @@ -0,0 +1,140 @@ +/* + * 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.deployment.rp.autoconf; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PersistencyManager { + + private final File m_root; + + public PersistencyManager(File root) { + m_root = root; + } + + /** + * Stores a resource. + * + * @param name Name of the resource. + * @param configs List of AutoConfResources representing the specified resource. + * @throws IOException If the resource could not be stored. + */ + public void store(String name, List configs) throws IOException { + if (configs.isEmpty()) { + return; + } + File targetDir = m_root; + name = name.replaceAll("/", File.separator); + if (name.startsWith(File.separator)) { + name = name.substring(1); + } + int lastSeparator = name.lastIndexOf(File.separator); + File target = null; + if (lastSeparator != -1) { + targetDir = new File(targetDir, name.substring(0, lastSeparator)); + targetDir.mkdirs(); + } + target = new File(targetDir, name.substring(lastSeparator + 1)); + + ObjectOutputStream out = null; + try { + out = new ObjectOutputStream(new FileOutputStream(target)); + out.writeObject(configs); + } finally { + if (out != null) { + try { + out.close(); + } catch (Exception e) { + // not much we can do + } + } + } + } + + /** + * Deletes a resource. + * + * @param name Name of the resource. + * @throws IOException If the resource could not be deleted. + */ + public void delete(String name) throws IOException { + name = name.replace('/', File.separatorChar); + File target = new File(m_root, name); + if (!target.delete()) { + throw new IOException("Unable to delete file: " + target.getAbsolutePath()); + } + while (target.getParentFile().list().length == 0 && !target.getParentFile().getAbsolutePath().equals(m_root.getAbsolutePath())) { + target = target.getParentFile(); + target.delete(); + } + } + + /** + * Loads a stored resource. + * + * @param name Name of the resource. + * @return List of AutoConfResources representing the specified resource, if the resource is unknown an empty list is returned. + * @throws IOException If the resource could not be properly read. + */ + public List load(String name) throws IOException { + name = name.replaceAll("/", File.separator); + List resources = new ArrayList(); + File resourcesFile = new File(m_root, name); + if (resourcesFile.exists()) { + ObjectInputStream in = null; + try { + in = new ObjectInputStream(new FileInputStream(resourcesFile)); + resources = (List) in.readObject(); + } catch (FileNotFoundException fnfe) { + throw new IOException("Resource does not exist: " + name); + } catch (ClassNotFoundException cnfe) { + throw new IOException("Unable to recreate persisted object from file: " + name); + } finally { + if (in != null) { + try { + in.close(); + } catch (Exception e) { + // not much we can do + } + } + } + } + return resources; + } + + /** + * Loads all stored resources. + * + * @return A map containing all persisted resources which is typed > + * @throws IOException If not all resources could be loaded. + */ + public Map loadAll() throws IOException { + return new HashMap(); + } +} Modified: felix/trunk/deploymentadmin/pom.xml URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/pom.xml?rev=682415&r1=682414&r2=682415&view=diff ============================================================================== --- felix/trunk/deploymentadmin/pom.xml (original) +++ felix/trunk/deploymentadmin/pom.xml Mon Aug 4 08:01:29 2008 @@ -30,5 +30,6 @@ 1 service + autoconf