Author: [email protected] Date: Tue Nov 22 17:35:49 2011 New Revision: 1750
Log: AMDATU-472 Initial commit of fileinstall metatype plugin Added: trunk/amdatu-core/fileinstall-metatype/ trunk/amdatu-core/fileinstall-metatype/LICENSE trunk/amdatu-core/fileinstall-metatype/NOTICE trunk/amdatu-core/fileinstall-metatype/pom.xml trunk/amdatu-core/fileinstall-metatype/src/ trunk/amdatu-core/fileinstall-metatype/src/main/ trunk/amdatu-core/fileinstall-metatype/src/main/java/ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/AttributeDefinitionImpl.java trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeFileInstall.java trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetatypeArtifactInstaller.java trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/ObjectClassDefinitionImpl.java Added: trunk/amdatu-core/fileinstall-metatype/LICENSE ============================================================================== --- (empty file) +++ trunk/amdatu-core/fileinstall-metatype/LICENSE Tue Nov 22 17:35:49 2011 @@ -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: trunk/amdatu-core/fileinstall-metatype/NOTICE ============================================================================== --- (empty file) +++ trunk/amdatu-core/fileinstall-metatype/NOTICE Tue Nov 22 17:35:49 2011 @@ -0,0 +1,18 @@ +Amdatu Core Fileinstall Metatype +Copyright 2010, 2011 The Amdatu 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. + +II. Used Software + +This product uses software developed at +The OSGi Alliance (http://www.osgi.org/). +Copyright (c) OSGi Alliance (2000, 2007). +Licensed under the Apache License 2.0. + +III. License Summary +- Apache License 2.0 Added: trunk/amdatu-core/fileinstall-metatype/pom.xml ============================================================================== --- (empty file) +++ trunk/amdatu-core/fileinstall-metatype/pom.xml Tue Nov 22 17:35:49 2011 @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Copyright (c) 2010, 2011 The Amdatu Foundation + + 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.verning 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> + <parent> + <groupId>org.amdatu.core</groupId> + <artifactId>org.amdatu.core</artifactId> + <version>0.3.0-SNAPSHOT</version> + </parent> + + <packaging>bundle</packaging> + <name>Amdatu Core - Fileinstall Metatype support</name> + <description>An extension to Apache Felix File Install for metatype configuration</description> + <url>http://www.amdatu.org</url> + <artifactId>org.amdatu.core.fileinstall.metatype</artifactId> + + <!-- + Because we may donate this to Felix: + * source/target must remain 1.3 compliant + * additional dependencies must not introduced + --> + + <dependencies> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.fileinstall</artifactId> + <version>3.1.10</version> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.metatype</artifactId> + <version>1.0.4</version> + <exclusions> + <exclusion> + <groupId>org.apache.felix</groupId> + <artifactId>org.osgi.core</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.felix</groupId> + <artifactId>org.osgi.copmpendium</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.utils</artifactId> + <version>1.1.0</version> + <scope>provided</scope> + </dependency> + </dependencies> + <build> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <executions> + <execution> + <id>default-testCompile</id> + <phase>test-compile</phase> + <goals> + <goal>testCompile</goal> + </goals> + <configuration> + <source>1.3</source> + <target>1.3</target> + </configuration> + </execution> + <execution> + <id>default-compile</id> + <phase>compile</phase> + <goals> + <goal>compile</goal> + </goals> + <configuration> + <source>1.3</source> + <target>1.3</target> + </configuration> + </execution> + </executions> + <configuration> + <source>1.3</source> + <target>1.3</target> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-Activator>org.amdatu.core.fileinstall.metatype.internal.MetaTypeFileInstall</Bundle-Activator> + <Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName> + <Export-Package> + </Export-Package> + <Private-Package> + org.amdatu.core.fileinstall.metatype.internal + </Private-Package> + <Import-Package> + * + </Import-Package> + <Embed-Dependency> + </Embed-Dependency> + </instructions> + </configuration> + </plugin> + </plugins> + </build> +</project> Added: trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/AttributeDefinitionImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/AttributeDefinitionImpl.java Tue Nov 22 17:35:49 2011 @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010, 2011 The Amdatu Foundation + * + * 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.amdatu.core.fileinstall.metatype.internal; + +import org.apache.felix.metatype.AD; +import org.osgi.service.metatype.AttributeDefinition; + +/** + * Copy if org.apache.felix.deployment.rp.autoconf.AttributeDefinitionImpl + */ +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: trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeFileInstall.java ============================================================================== --- (empty file) +++ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetaTypeFileInstall.java Tue Nov 22 17:35:49 2011 @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2010, 2011 The Amdatu Foundation + * + * 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.amdatu.core.fileinstall.metatype.internal; + +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.felix.fileinstall.ArtifactInstaller; +import org.apache.felix.fileinstall.ArtifactListener; +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.Constants; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.log.LogService; +import org.osgi.service.metatype.MetaTypeService; +import org.osgi.util.tracker.ServiceTracker; + +/** + * A plugin for FileInstall that can handle MetaType files. + * + */ +public final class MetaTypeFileInstall implements BundleActivator { + + public static final String FILENAME_KEY = "org.apache.felix.fileinstall.metatype.file"; + + interface Logger { + public void log(int level, String message); + + public void log(int level, String message, Throwable exception); + + } + + private final Logger m_logger = new Logger() { + + public void log(int level, String message, Throwable exception) { + MetaTypeFileInstall.this.log(level, message, exception); + } + + public void log(int level, String message) { + MetaTypeFileInstall.this.log(level, message); + } + }; + + private BundleContext m_bundleContext; + private ServiceTracker m_configAdminAdaptor; + private ServiceTracker m_logServiceTracker; + private ServiceTracker m_metaTypeServiceTracker; + + public void start(BundleContext bundleContext) throws Exception { + m_bundleContext = bundleContext; + + m_logServiceTracker = new ServiceTracker(bundleContext, LogService.class.getName(), null); + m_logServiceTracker.open(); + + m_metaTypeServiceTracker = new ServiceTracker(bundleContext, MetaTypeService.class.getName(), null) { + + private volatile ServiceReference m_metaTypeServiceRef; + + public Object addingService(ServiceReference metaTypeServiceRef) { + + MetaTypeService metaTypeService = (MetaTypeService) super.addingService(metaTypeServiceRef); + if (metaTypeService == null) + return null; + + if (m_metaTypeServiceRef == null || metaTypeServiceRef.compareTo(m_metaTypeServiceRef) > 0) { + m_metaTypeServiceRef = metaTypeServiceRef; + if (m_configAdminAdaptor != null) + m_configAdminAdaptor.close(); + m_configAdminAdaptor = new ConfigAdminAdaptor(m_bundleContext, metaTypeService, m_logger); + m_configAdminAdaptor.open(); + } + return metaTypeService; + } + + public void modifiedService(ServiceReference metaTypeServiceRef, Object service) { + // TODO handle ranking change? + } + + public void removedService(ServiceReference metaTypeServiceRef, Object service) { + super.removedService(metaTypeServiceRef, service); + if (metaTypeServiceRef == m_metaTypeServiceRef) { + if (m_configAdminAdaptor != null) + m_configAdminAdaptor.close(); + + m_metaTypeServiceRef = getServiceReference(); + if (m_metaTypeServiceRef != null) { + MetaTypeService metaTypeService = (MetaTypeService) getService(m_metaTypeServiceRef); + m_configAdminAdaptor = new ConfigAdminAdaptor(m_bundleContext, metaTypeService, m_logger); + m_configAdminAdaptor.open(); + } + } + } + }; + m_metaTypeServiceTracker.open(); + } + + public void stop(BundleContext context) throws Exception { + m_metaTypeServiceTracker.close(); + m_logServiceTracker.close(); + } + + public void log(int level, String message) { + if (m_logServiceTracker == null) + return; + log(level, message, null); + } + + public void log(int level, String message, Throwable exception) { + if (m_logServiceTracker == null) + return; + Object[] services = m_logServiceTracker.getServices(); + if (services != null) { + for (int i = 0; i < services.length; i++) { + ((LogService) services[i]).log(level, message, exception); + } + } + } + + private static class ConfigAdminAdaptor extends ServiceTracker { + + private final BundleContext m_bundleContext; + private final MetaTypeService m_metaTypeService; + private final Logger m_logger; + + private final Map m_configAdminRefs = new HashMap(); + private final Map m_installerRegs = new HashMap(); + + public ConfigAdminAdaptor(BundleContext bundleContext, MetaTypeService metaTypeService, Logger logger) { + super(bundleContext, ConfigurationAdmin.class.getName(), null); + m_bundleContext = bundleContext; + m_metaTypeService = metaTypeService; + m_logger = logger; + } + + public Object addingService(ServiceReference reference) { + ConfigurationAdmin configAdmin = (ConfigurationAdmin) super.addingService(reference); + synchronized (m_configAdminRefs) { + if (!m_configAdminRefs.containsKey(reference)) { + m_logger.log(LogService.LOG_INFO, + "Registering metatype installer for ConfigurationAdmin with service.id " + + reference.getProperty(Constants.SERVICE_ID)); + registerMetatypeArtifactInstaller(reference, configAdmin); + } + } + return configAdmin; + } + + public void modifiedService(ServiceReference reference, Object service) { + synchronized (m_configAdminRefs) { + if (m_configAdminRefs.containsKey(reference)) { + m_logger.log(LogService.LOG_INFO, + "Updating metatype installer for ConfigurationAdmin with service.id " + + reference.getProperty(Constants.SERVICE_ID)); + unregisterMetatypeArtifactInstaller(reference); + registerMetatypeArtifactInstaller(reference, (ConfigurationAdmin) service); + } + } + } + + public void removedService(ServiceReference reference, Object service) { + synchronized (m_configAdminRefs) { + if (m_configAdminRefs.containsKey(reference)) { + m_logger.log(LogService.LOG_INFO, + "Unregistering metatype installer for ConfigurationAdmin with service.id " + + reference.getProperty(Constants.SERVICE_ID)); + unregisterMetatypeArtifactInstaller(reference); + } + } + super.removedService(reference, service); + } + + private void registerMetatypeArtifactInstaller(ServiceReference reference, ConfigurationAdmin configAdmin) { + MetatypeArtifactInstaller installer = new MetatypeArtifactInstaller(m_bundleContext, configAdmin, + m_metaTypeService, m_logger); + ServiceRegistration installerReg = m_bundleContext.registerService( + new String[] { + ArtifactListener.class.getName(), + ArtifactInstaller.class.getName() + }, + installer, new Properties()); + m_configAdminRefs.put(reference, installerReg); + m_installerRegs.put(installerReg, installer); + } + + private void unregisterMetatypeArtifactInstaller(ServiceReference reference) { + ServiceRegistration installerReg = (ServiceRegistration) m_configAdminRefs.remove(reference); + m_installerRegs.remove(installerReg); + installerReg.unregister(); + } + }; + +} Added: trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetatypeArtifactInstaller.java ============================================================================== --- (empty file) +++ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/MetatypeArtifactInstaller.java Tue Nov 22 17:35:49 2011 @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2010, 2011 The Amdatu Foundation + * + * 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.amdatu.core.fileinstall.metatype.internal; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.Dictionary; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.amdatu.core.fileinstall.metatype.internal.MetaTypeFileInstall.Logger; +import org.apache.felix.fileinstall.ArtifactInstaller; +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.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; + +public final class MetatypeArtifactInstaller implements ArtifactInstaller { + + private final BundleContext m_bundleContext; + private final ConfigurationAdmin m_configAdmin; + private final MetaTypeService m_metaTypeService; + private final Logger m_logger; + + public MetatypeArtifactInstaller(BundleContext bundleContext, ConfigurationAdmin configAdmin, + MetaTypeService metaTypeService, Logger logger) { + m_bundleContext = bundleContext; + m_configAdmin = configAdmin; + m_metaTypeService = metaTypeService; + m_logger = logger; + } + + public boolean canHandle(File artifact) { + if (!artifact.getName().endsWith(".xml")) { + return false; + } + MetaData metaData = null; + try { + metaData = readMetaData(artifact); + } + catch (Exception e) { + m_logger.log(LogService.LOG_DEBUG, + "Unable to parse metatype file " + artifact.getName(), e); + } + return metaData != null; + } + + public void install(File artifact) throws Exception { + m_logger.log(LogService.LOG_DEBUG, + "Installing metatype configuration file " + artifact.getName()); + + MetaData metaData = readMetaData(artifact); + if (metaData == null) { + m_logger.log(LogService.LOG_ERROR, + "Metadata was null after parsing metatype configuration file " + artifact.getName()); + return; + } + + Map designates = metaData.getDesignates(); + if (designates == null) { + m_logger.log(LogService.LOG_WARNING, + "No designates found in metatype configuration file " + artifact.getName()); + } + + Map localOcds = metaData.getObjectClassDefinitions(); + if (localOcds == null) { + localOcds = Collections.EMPTY_MAP; + } + + Iterator i = designates.keySet().iterator(); + while (i.hasNext()) { + Designate designate = (Designate) designates.get(i.next()); + + ObjectClassDefinition ocd = null; + String ocdRef = designate.getObject().getOcdRef(); + OCD localOcd = (OCD) localOcds.get(ocdRef); + if (localOcd != null) { + ocd = new ObjectClassDefinitionImpl(localOcd); + } + else { + ocd = getMetaTypeOCD(metaData, designate); + if (ocd == null) { + m_logger.log( + LogService.LOG_WARNING, + "No definition found for ocdfref " + designate.getObject().getOcdRef() + + " in metatype configuration file " + + artifact.getName()); + continue; + } + } + + Dictionary dict = getProperties(designate, ocd); + if (dict == null) { + m_logger.log( + LogService.LOG_WARNING, + "Unable to get properties for designate " + designate.getPid() + " in metatype configuration file " + + artifact.getName()); + continue; + } + + Configuration configuration = null; + if (!(designate.getFactoryPid() == null || "".equals(designate.getFactoryPid()))) { + configuration = + m_configAdmin.createFactoryConfiguration(designate.getFactoryPid(), null); + } + else { + configuration = m_configAdmin.getConfiguration(designate.getPid(), null); + } + + if (configuration != null) { + dict.put(MetaTypeFileInstall.FILENAME_KEY, artifact.getName()); + configuration.update(dict); + } + } + } + + public void update(File artifact) throws Exception { + m_logger.log(LogService.LOG_DEBUG, + "Updating metatype configuration file " + artifact.getName()); + + uninstall(artifact); + install(artifact); + } + + public void uninstall(File artifact) throws Exception { + m_logger.log(LogService.LOG_DEBUG, + "Uninstalling metatype configuration file " + artifact.getName()); + + Configuration[] configs = + m_configAdmin.listConfigurations("(" + MetaTypeFileInstall.FILENAME_KEY + "=" + artifact.getName() + ")"); + if (configs != null) { + for (int i = 0; i < configs.length; i++) { + configs[i].delete(); + } + } + } + + private MetaData readMetaData(File artifact) throws Exception { + final InputStream stream = new BufferedInputStream(new FileInputStream(artifact)); + final MetaDataReader reader = new MetaDataReader(); + + MetaData metaData = null; + try { + metaData = reader.parse(stream); + } + catch (Exception e) { + m_logger.log(LogService.LOG_ERROR, + "Exception occured while parsing metatype configuration file " + artifact.getName(), e); + } + finally { + stream.close(); + } + return metaData; + } + + /* + * Based on org.apache.felix.deployment.rp.autoconf.AutoConfResourceProcessor + */ + private ObjectClassDefinition getMetaTypeOCD(MetaData data, Designate designate) { + + ObjectClassDefinition ocd = null; + String ocdRef = designate.getObject().getOcdRef(); + + String bundleLocation = designate.getBundleLocation(); + boolean allBundles = (bundleLocation == null || "".equals(bundleLocation) || "*".equals(bundleLocation)); + + String pid = isFactoryConfig(designate) ? pid = designate.getFactoryPid() : designate.getPid(); + + Bundle[] bundles = m_bundleContext.getBundles(); + for (int i = 0; i < bundles.length; i++) { + if (allBundles || bundleLocation.equals(bundles[i].getLocation())) { + MetaTypeInformation mti = m_metaTypeService.getMetaTypeInformation(bundles[i]); + if (mti != null) { + ObjectClassDefinition tempOcd = mti.getObjectClassDefinition(pid, null); + if (tempOcd != null && ocdRef.equals(tempOcd.getID())) { + ocd = tempOcd; + break; + } + } + } + } + return ocd; + } + + /* + * Based on org.apache.felix.deployment.rp.autoconf.AutoConfResourceProcessor + */ + private boolean isFactoryConfig(Designate designate) { + String factoryPid = designate.getFactoryPid(); + return (factoryPid != null || !"".equals(factoryPid)); + } + + /* + * Based on org.apache.felix.deployment.rp.autoconf.AutoConfResourceProcessor + */ + private Dictionary getProperties(Designate designate, ObjectClassDefinition ocd) { + 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())) { + Object value = getValue(attribute, ad); + if (value == null) { + if (designate.isOptional()) { + break; + } + else { + return null; + } + } + properties.put(adRef, value); + found = true; + break; + } + } + if (!found) { + if (designate.isOptional()) { + break; + } + else { + return null; + } + } + } + + return properties; + } + + /* + * Copied from org.apache.felix.deployment.rp.autoconf.AutoConfResourceProcessor + */ + private Object getValue(Attribute attribute, AttributeDefinition ad) { + if (attribute == null || ad == null || !attribute.getAdRef().equals(ad.getID())) { + return null; + } + String[] content = attribute.getContent(); + 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: + return null; + } + } + } + catch (NumberFormatException nfe) { + return null; + } + + 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: trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/ObjectClassDefinitionImpl.java ============================================================================== --- (empty file) +++ trunk/amdatu-core/fileinstall-metatype/src/main/java/org/amdatu/core/fileinstall/metatype/internal/ObjectClassDefinitionImpl.java Tue Nov 22 17:35:49 2011 @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2010, 2011 The Amdatu Foundation + * + * 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.amdatu.core.fileinstall.metatype.internal; + +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; + +/** + * Copy if org.apache.felix.deployment.rp.autoconf.ObjectClassDefinitionImpl + */ +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 { + return null; + } + + public String getDescription() { + return m_ocd.getDescription(); + } + + public String getID() { + return m_ocd.getID(); + } + + public String getName() { + return m_ocd.getName(); + } +} _______________________________________________ Amdatu-commits mailing list [email protected] http://lists.amdatu.org/mailman/listinfo/amdatu-commits
