You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fm...@apache.org on 2007/04/11 20:27:14 UTC
svn commit: r527597 [1/2] - in /incubator/felix/trunk/metatype: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/felix/ src/main/java/org/apache/felix/metatype/
src/main/java/org/apache/felix/metaty...
Author: fmeschbe
Date: Wed Apr 11 11:27:12 2007
New Revision: 527597
URL: http://svn.apache.org/viewvc?view=rev&rev=527597
Log:
FELIX-20 Implement Metatype Service (Initial Checkin)
Added:
incubator/felix/trunk/metatype/ (with props)
incubator/felix/trunk/metatype/pom.xml (with props)
incubator/felix/trunk/metatype/src/
incubator/felix/trunk/metatype/src/main/
incubator/felix/trunk/metatype/src/main/java/
incubator/felix/trunk/metatype/src/main/java/org/
incubator/felix/trunk/metatype/src/main/java/org/apache/
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/AD.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Attribute.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DefaultMetaTypeProvider.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Designate.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DesignateObject.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaData.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/OCD.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/Activator.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedBase.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedObjectClassDefinition.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/MetaTypeInformationImpl.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/MetaTypeServiceImpl.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/ServiceMetaTypeInformation.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/l10n/
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/l10n/BundleResources.java (with props)
incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/l10n/Resources.java (with props)
incubator/felix/trunk/metatype/src/test/
incubator/felix/trunk/metatype/src/test/java/
incubator/felix/trunk/metatype/src/test/java/org/
incubator/felix/trunk/metatype/src/test/java/org/apache/
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/metatype/
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/metatype/ADTest.java (with props)
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/metatype/MetaDataReaderTest.java (with props)
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/metatype/MockBundle.java (with props)
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/metatype/MockBundleContext.java (with props)
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/metatype/internal/
incubator/felix/trunk/metatype/src/test/java/org/apache/felix/metatype/internal/MetaTypeServiceImplTest.java (with props)
Propchange: incubator/felix/trunk/metatype/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Apr 11 11:27:12 2007
@@ -0,0 +1,4 @@
+target
+.classpath
+.project
+.settings
Added: incubator/felix/trunk/metatype/pom.xml
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/pom.xml?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/pom.xml (added)
+++ incubator/felix/trunk/metatype/pom.xml Wed Apr 11 11:27:12 2007
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>felix</artifactId>
+ <version>0.9.0-incubator-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>org.apache.felix.metatype</artifactId>
+ <packaging>bundle</packaging>
+
+ <name>Apache Felix Metatype Service</name>
+ <description>
+ Implementation of the OSGi Metatype Service Specification 1.1
+ </description>
+
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>net.sf.kxml</groupId>
+ <artifactId>kxml2</artifactId>
+ <version>2.2.2</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>0.9.0-incubator-SNAPSHOT</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Category>osgi</Bundle-Category>
+ <Export-Package>
+ org.apache.felix.metatype,
+ org.osgi.service.metatype; version=1.1
+ </Export-Package>
+ <Private-Package>
+ org.apache.felix.metatype.internal,
+ org.apache.felix.metatype.internal.l10n,
+ org.kxml2.io,
+ org.xmlpull.v1
+ </Private-Package>
+ <Bundle-Activator>
+ org.apache.felix.metatype.internal.Activator
+ </Bundle-Activator>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Propchange: incubator/felix/trunk/metatype/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/AD.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/AD.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/AD.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/AD.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,480 @@
+/*
+ * 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.metatype;
+
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.metatype.internal.Activator;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.AttributeDefinition;
+
+
+/**
+ * The <code>AD</code> class represents the <code>AD</code> element of the
+ * meta type descriptor.
+ *
+ * @author fmeschbe
+ */
+public class AD
+{
+
+ /**
+ * The message returned from the {@link #validate(String)} method if the
+ * value is not any of the specified {@link #getOptionValues() option values}
+ * (value is "%not a valid option").
+ */
+ public static final String VALIDATE_NOT_A_VALID_OPTION = "%not a valid option";
+
+ /**
+ * The message returned from the {@link #validate(String)} method if the
+ * value is greater than the specified {@link #getMax() maximum value}
+ * (value is "%greater than maximum").
+ */
+ public static final String VALIDATE_GREATER_THAN_MAXIMUM = "%greater than maximum";
+
+ /**
+ * The message returned from the {@link #validate(String)} method if the
+ * value is less than the specified {@link #getMin() minimum value}
+ * (value is "%less than minimum").
+ */
+ public static final String VALIDATE_LESS_THAN_MINIMUM = "%less than minimum";
+
+ private String id;
+ private String name;
+ private String description;
+ private int type;
+ private int cardinality = 0;
+ private String[] optionLabels;
+ private String[] optionValues;
+ private String[] defaultValue;
+ private String min;
+ private String max;
+ private boolean isRequired = true;
+
+
+ public String getID()
+ {
+ return id;
+ }
+
+
+ public String getName()
+ {
+ return name;
+ }
+
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+
+ public int getType()
+ {
+ return type;
+ }
+
+
+ public int getCardinality()
+ {
+ return cardinality;
+ }
+
+
+ public String[] getOptionLabels()
+ {
+ return optionLabels;
+ }
+
+
+ public String[] getOptionValues()
+ {
+ return optionValues;
+ }
+
+
+ public String[] getDefaultValue()
+ {
+ return defaultValue;
+ }
+
+
+ public String getMin()
+ {
+ return min;
+ }
+
+
+ public String getMax()
+ {
+ return max;
+ }
+
+
+ public boolean isRequired()
+ {
+ return isRequired;
+ }
+
+
+ /**
+ * Implements validation of the <code>valueString</code> and returns an
+ * indication of the success:
+ * <dl>
+ * <dt><code>null</code>
+ * <dd>If neither a {@link #getMin() minimal value} nor a
+ * {@link #getMax() maximal value} nor any
+ * {@link #getOptionValues() optional values} are defined in this
+ * instance, validation cannot be performed.
+ * <dt>Empty String
+ * <dd>If validation succeeds. This value is also returned if the
+ * <code>valueString</code> is empty or <code>null</code> or cannot be
+ * converted into a numeric type.
+ * <dt><b>%</b>message
+ * <dd>If the value falls below the minimum, higher than the maximum or is
+ * not any of the option values, an explanatory message, which may be
+ * localized is returned. If any of the minimum, maximum or option
+ * values is <code>null</code>, the respective value is not checked.
+ * </dl>
+ *
+ * @param valueString The string representation of the value to validate.
+ *
+ * @return As explained above.
+ *
+ * @see #VALIDATE_GREATER_THAN_MAXIMUM
+ * @see #VALIDATE_LESS_THAN_MINIMUM
+ * @see #VALIDATE_NOT_A_VALID_OPTION
+ */
+ public String validate( String valueString )
+ {
+ // no validation if no min and max
+ if ( getMin() == null && getMax() == null && getOptionValues() == null )
+ {
+ return null;
+ }
+
+ Comparable value = convertToType( valueString );
+ if ( value == null )
+ {
+ return ""; // accept null value
+ }
+
+ Comparable other = convertToType( getMin() );
+ if ( other != null )
+ {
+ if ( value.compareTo( other ) < 0 )
+ {
+ return VALIDATE_LESS_THAN_MINIMUM;
+ }
+ }
+
+ other = convertToType( getMax() );
+ if ( other != null )
+ {
+ if ( value.compareTo( other ) > 0 )
+ {
+ return VALIDATE_GREATER_THAN_MAXIMUM;
+ }
+ }
+
+ String[] optionValues = getOptionValues();
+ if ( optionValues != null )
+ {
+ for ( int i = 0; i < optionValues.length; i++ )
+ {
+ other = convertToType( optionValues[i] );
+ if ( value.compareTo( other ) == 0 )
+ {
+ // one of the option values
+ return "";
+ }
+ }
+
+ // not any of the option values, fail
+ return VALIDATE_NOT_A_VALID_OPTION;
+ }
+
+ // finally, we accept the value
+ return "";
+ }
+
+
+ //--------- Setters for setting up this instance --------------------------
+
+ /**
+ * @param id the id to set
+ */
+ public void setID( String id )
+ {
+ this.id = id;
+ }
+
+
+ /**
+ * @param name the name to set
+ */
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+
+ /**
+ * @param description the description to set
+ */
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+
+ /**
+ * @param type the type to set
+ */
+ public void setType( String typeString )
+ {
+ this.type = toType( typeString );
+ }
+
+
+ /**
+ * @param cardinality the cardinality to set
+ */
+ public void setCardinality( int cardinality )
+ {
+ this.cardinality = cardinality;
+ }
+
+
+ /**
+ * @param optionLabels the optionLabels to set
+ */
+ public void setOptions( Map options )
+ {
+ optionLabels = new String[options.size()];
+ optionValues = new String[options.size()];
+ int i = 0;
+ for ( Iterator oi = options.entrySet().iterator(); oi.hasNext(); i++ )
+ {
+ Map.Entry entry = ( Map.Entry ) oi.next();
+ optionValues[i] = String.valueOf( entry.getKey() );
+ optionLabels[i] = String.valueOf( entry.getValue() );
+ }
+ }
+
+
+ /**
+ * @param defaultValue the defaultValue to set
+ */
+ public void setDefaultValue( String defaultValue )
+ {
+ this.defaultValue = splitList( defaultValue );
+ }
+
+
+ /**
+ * @param min the min to set
+ */
+ public void setMin( String min )
+ {
+ this.min = min;
+ }
+
+
+ /**
+ * @param max the max to set
+ */
+ public void setMax( String max )
+ {
+ this.max = max;
+ }
+
+
+ /**
+ * @param defaultValue the defaultValue to set
+ */
+ public void setDefaultValue( String[] defaultValue )
+ {
+ this.defaultValue = ( String[] ) defaultValue.clone();
+ }
+
+
+ /**
+ * @param isRequired the isRequired to set
+ */
+ public void setRequired( boolean isRequired )
+ {
+ this.isRequired = isRequired;
+ }
+
+
+ public static int toType( String typeString )
+ {
+ if ( "String".equals( typeString ) )
+ {
+ return AttributeDefinition.STRING;
+ }
+ else if ( "Long".equals( typeString ) )
+ {
+ return AttributeDefinition.LONG;
+ }
+ else if ( "Double".equals( typeString ) )
+ {
+ return AttributeDefinition.DOUBLE;
+ }
+ else if ( "Float".equals( typeString ) )
+ {
+ return AttributeDefinition.FLOAT;
+ }
+ else if ( "Integer".equals( typeString ) )
+ {
+ return AttributeDefinition.INTEGER;
+ }
+ else if ( "Byte".equals( typeString ) )
+ {
+ return AttributeDefinition.BYTE;
+ }
+ else if ( "Char".equals( typeString ) )
+ {
+ return AttributeDefinition.CHARACTER;
+ }
+ else if ( "Boolean".equals( typeString ) )
+ {
+ return AttributeDefinition.BOOLEAN;
+ }
+ else if ( "Short".equals( typeString ) )
+ {
+ return AttributeDefinition.SHORT;
+ }
+
+ // finally fall back to string for illegal values
+ return AttributeDefinition.STRING;
+ }
+
+
+ public static String[] splitList( String listString )
+ {
+ // return nothing ...
+ if ( listString == null )
+ {
+ return null;
+ }
+
+ List values = new ArrayList();
+ boolean escape = false;
+ StringBuffer buf = new StringBuffer();
+ for ( int i = 0; i < listString.length(); i++ )
+ {
+ char c = listString.charAt( i );
+
+ if ( escape )
+ {
+ // just go ahead
+ escape = false;
+ }
+ else if ( c == ',' )
+ {
+ String value = buf.toString().trim();
+ if ( value.length() > 0 )
+ {
+ values.add( value );
+ }
+ buf.delete( 0, buf.length() );
+ continue;
+ }
+ else if ( c == '\\' )
+ {
+ escape = true;
+ continue;
+ }
+
+ buf.append( c );
+ }
+
+ // add last string
+ if ( buf.length() > 0 )
+ {
+ String value = buf.toString().trim();
+ if ( value.length() > 0 )
+ {
+ values.add( value );
+ }
+ }
+
+ return values.isEmpty() ? null : ( String[] ) values.toArray( new String[values.size()] );
+ }
+
+
+ protected Comparable convertToType( final String value )
+ {
+ if ( value != null && value.length() > 0 )
+ {
+ try
+ {
+ switch ( getType() )
+ {
+ case AttributeDefinition.BOOLEAN:
+ // Boolean is only Comparable starting with Java 5
+ return new ComparableBoolean(value);
+ case AttributeDefinition.CHARACTER:
+ return new Character( value.charAt( 0 ) );
+ case AttributeDefinition.BYTE:
+ return Byte.valueOf( value );
+ case AttributeDefinition.SHORT:
+ return Short.valueOf( value );
+ case AttributeDefinition.INTEGER:
+ return Integer.valueOf( value );
+ case AttributeDefinition.LONG:
+ return Long.valueOf( value );
+ case AttributeDefinition.FLOAT:
+ return Float.valueOf( value );
+ case AttributeDefinition.DOUBLE:
+ return Double.valueOf( value );
+ case AttributeDefinition.STRING:
+ default:
+ return value;
+ }
+ }
+ catch ( NumberFormatException nfe )
+ {
+ Activator.log( LogService.LOG_INFO, "Cannot convert value '" + value + "'", nfe );
+ }
+ }
+
+ return null;
+ }
+
+ private static class ComparableBoolean implements Comparable {
+ private boolean value;
+
+ ComparableBoolean(String boolValue) {
+ value = Boolean.valueOf(boolValue).booleanValue();
+ }
+
+ public int compareTo(Object obj) {
+ ComparableBoolean cb = (ComparableBoolean) obj;
+ return (cb.value == value ? 0 : (value ? 1 : -1));
+ }
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/AD.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/AD.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Attribute.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Attribute.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Attribute.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Attribute.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,78 @@
+/*
+ * 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.metatype;
+
+
+/**
+ * The <code>Attribute</code> TODO
+ *
+ * @author fmeschbe
+ * @version $Rev:$, $Date:$
+ */
+public class Attribute
+{
+
+ private String adRef;
+ private String[] content;
+
+
+ public String getAdRef()
+ {
+ return adRef;
+ }
+
+
+ public void setAdRef( String adRef )
+ {
+ this.adRef = adRef;
+ }
+
+
+ public String[] getContent()
+ {
+ return ( String[] ) content.clone();
+ }
+
+
+ public void addContent( String[] added )
+ {
+ if ( added != null && added.length > 0 )
+ {
+ if ( content == null )
+ {
+ content = ( String[] ) added.clone();
+ }
+ else
+ {
+ String[] newContent = new String[content.length + added.length];
+ System.arraycopy( content, 0, newContent, 0, content.length );
+ System.arraycopy( added, 0, newContent, content.length, added.length );
+ }
+ }
+ }
+
+
+ public void addContent( String content )
+ {
+ if ( content != null )
+ {
+ addContent( AD.splitList( content ) );
+ }
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Attribute.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Attribute.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DefaultMetaTypeProvider.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DefaultMetaTypeProvider.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DefaultMetaTypeProvider.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DefaultMetaTypeProvider.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,197 @@
+/*
+ * 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.metatype;
+
+
+import java.net.URL;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.felix.metatype.internal.LocalizedObjectClassDefinition;
+import org.apache.felix.metatype.internal.l10n.BundleResources;
+import org.apache.felix.metatype.internal.l10n.Resources;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.MetaTypeService;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+
+/**
+ * The <code>DefaultMetaTypeProvider</code> class is an implementation of the
+ * <code>MetaTypeProvider</code> interface whichis configured for a given
+ * bundle using a {@link MetaData} object.
+ * <p>
+ * This class may be used by clients, e.g. <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code> implementations to easily also implement
+ * the <code>MetaTypeProvider</code> interface.
+ *
+ * @author fmeschbe
+ */
+public class DefaultMetaTypeProvider implements MetaTypeProvider
+{
+
+ private final Bundle bundle;
+
+ private String localePrefix;
+ private Map objectClassDefinitions;
+ private Map designates;
+
+ private Map locales;
+
+
+ public DefaultMetaTypeProvider( Bundle bundle, MetaData metadata )
+ {
+ this.bundle = bundle;
+
+ // copy from holder
+ if ( metadata.getObjectClassDefinitions() == null )
+ {
+ objectClassDefinitions = Collections.EMPTY_MAP;
+ }
+ else
+ {
+ Map copy = new HashMap( metadata.getObjectClassDefinitions() );
+ objectClassDefinitions = Collections.unmodifiableMap( copy );
+ }
+ if ( metadata.getDesignates() == null )
+ {
+ designates = Collections.EMPTY_MAP;
+ }
+ else
+ {
+ Map copy = new HashMap( metadata.getDesignates() );
+ designates = Collections.unmodifiableMap( copy );
+ }
+
+ localePrefix = metadata.getLocalePrefix();
+ if ( localePrefix == null )
+ {
+ localePrefix = ( String ) bundle.getHeaders().get( Constants.BUNDLE_LOCALIZATION );
+ if ( localePrefix == null )
+ {
+ localePrefix = Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
+ }
+ }
+ else
+ {
+ localePrefix = MetaTypeService.METATYPE_DOCUMENTS_LOCATION + "/" + localePrefix;
+ }
+ }
+
+
+ /**
+ * Returns the <code>Bundle</code> to which this instance belongs.
+ */
+ public Bundle getBundle()
+ {
+ return bundle;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.metatype.MetaTypeProvider#getLocales()
+ */
+ public String[] getLocales()
+ {
+ if ( locales == null )
+ {
+ String path;
+ String pattern;
+ int lastSlash = localePrefix.lastIndexOf( '/' );
+ if ( lastSlash < 0 )
+ {
+ path = "/";
+ pattern = localePrefix;
+ }
+ else
+ {
+ path = localePrefix.substring( 0, lastSlash );
+ pattern = localePrefix.substring( lastSlash + 1 );
+ }
+
+ Enumeration entries = getBundle().findEntries( path, pattern + "*.properties", false );
+ locales = new TreeMap();
+ while ( entries.hasMoreElements() )
+ {
+ URL url = ( URL ) entries.nextElement();
+ String name = url.getPath();
+ name = name.substring( name.lastIndexOf( '/' ) + 1 + pattern.length(), name.length()
+ - ".properties".length() );
+ if ( name.startsWith( "_" ) )
+ {
+ name = name.substring( 1 );
+ }
+ locales.put( name, url );
+ }
+ }
+
+ // no locales found
+ if ( locales.isEmpty() )
+ {
+ return null;
+ }
+
+ return ( String[] ) locales.keySet().toArray( new String[locales.size()] );
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.osgi.service.metatype.MetaTypeProvider#getObjectClassDefinition(java.lang.String, java.lang.String)
+ */
+ public ObjectClassDefinition getObjectClassDefinition( String id, String locale )
+ {
+ Designate designate = getDesignate( id );
+ if ( designate == null || designate.getObject() == null )
+ {
+ return null;
+ }
+
+ String ocdRef = designate.getObject().getOcdRef();
+ OCD ocd = ( OCD ) objectClassDefinitions.get( ocdRef );
+ if ( ocd == null )
+ {
+ return null;
+ }
+
+ Resources resources = BundleResources.getResources( bundle, localePrefix, locale );
+ return new LocalizedObjectClassDefinition( bundle, ocd, resources );
+ }
+
+
+ public Designate getDesignate( String pid )
+ {
+ return ( Designate ) designates.get( pid );
+ }
+
+ protected Map getObjectClassDefinitions()
+ {
+ return objectClassDefinitions;
+ }
+
+
+ protected Map getDesignates()
+ {
+ return designates;
+ }
+
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DefaultMetaTypeProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DefaultMetaTypeProvider.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Designate.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Designate.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Designate.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Designate.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,150 @@
+/*
+ * 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.metatype;
+
+
+/**
+ * The <code>Designate</code> class represents the <code>Designate</code>
+ * element of the meta type descriptor.
+ *
+ * @author fmeschbe
+ */
+public class Designate
+{
+
+ private String pid;
+
+ private String factoryPid;
+
+ private String bundleLocation;
+
+ private boolean optional;
+
+ private boolean merge;
+
+ private DesignateObject object;
+
+
+ /**
+ * @return the bundleLocation
+ */
+ public String getBundleLocation()
+ {
+ return bundleLocation;
+ }
+
+
+ /**
+ * @return the factoryPid
+ */
+ public String getFactoryPid()
+ {
+ return factoryPid;
+ }
+
+
+ /**
+ * @return the merge
+ */
+ public boolean isMerge()
+ {
+ return merge;
+ }
+
+
+ /**
+ * @return the optional
+ */
+ public boolean isOptional()
+ {
+ return optional;
+ }
+
+
+ /**
+ * @return the pid
+ */
+ public String getPid()
+ {
+ return pid;
+ }
+
+
+ /**
+ * @return the object
+ */
+ public DesignateObject getObject()
+ {
+ return object;
+ }
+
+
+ /**
+ * @param bundleLocation the bundleLocation to set
+ */
+ public void setBundleLocation( String bundleLocation )
+ {
+ this.bundleLocation = bundleLocation;
+ }
+
+
+ /**
+ * @param factoryPid the factoryPid to set
+ */
+ public void setFactoryPid( String factoryPid )
+ {
+ this.factoryPid = factoryPid;
+ }
+
+
+ /**
+ * @param merge the merge to set
+ */
+ public void setMerge( boolean merge )
+ {
+ this.merge = merge;
+ }
+
+
+ /**
+ * @param optional the optional to set
+ */
+ public void setOptional( boolean optional )
+ {
+ this.optional = optional;
+ }
+
+
+ /**
+ * @param pid the pid to set
+ */
+ public void setPid( String pid )
+ {
+ this.pid = pid;
+ }
+
+
+ /**
+ * @param object the object to set
+ */
+ public void setObject( DesignateObject object )
+ {
+ this.object = object;
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Designate.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/Designate.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DesignateObject.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DesignateObject.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DesignateObject.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DesignateObject.java Wed Apr 11 11:27:12 2007
@@ -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.metatype;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+/**
+ * The <code>DesignateObject</code> class represents the <code>Object</code> element of
+ * the meta type descriptor.
+ *
+ * @author fmeschbe
+ */
+public class DesignateObject
+{
+
+ private String ocdRef;
+ private List attributes;
+
+
+ public String getOcdRef()
+ {
+ return ocdRef;
+ }
+
+
+ public void setOcdRef( String ocdRef )
+ {
+ this.ocdRef = ocdRef;
+ }
+
+
+ public List getAttributes()
+ {
+ return attributes;
+ }
+
+
+ public void addAttribute( Attribute attribute )
+ {
+ if ( attribute != null )
+ {
+ if ( attributes == null )
+ {
+ attributes = new ArrayList();
+ }
+ attributes.add( attribute );
+ }
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DesignateObject.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/DesignateObject.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaData.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaData.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaData.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaData.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,91 @@
+/*
+ * 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.metatype;
+
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+/**
+ * The <code>MetaData</code> class represents the <code>MetaData</code>
+ * element of the meta type descriptor.
+ *
+ * @author fmeschbe
+ */
+public class MetaData
+{
+
+ private String localePrefix;
+ private Map objectClassDefinitions;
+ private Map designates;
+
+
+ public String getLocalePrefix()
+ {
+ return localePrefix;
+ }
+
+
+ public void setLocalePrefix( String localePrefix )
+ {
+ this.localePrefix = localePrefix;
+ }
+
+
+ public Map getObjectClassDefinitions()
+ {
+ return objectClassDefinitions;
+ }
+
+
+ public void addObjectClassDefinition( OCD objectClassDefinition )
+ {
+ if ( objectClassDefinition != null )
+ {
+ if ( objectClassDefinitions == null )
+ {
+ objectClassDefinitions = new LinkedHashMap();
+ }
+
+ objectClassDefinitions.put( objectClassDefinition.getID(), objectClassDefinition );
+ }
+ }
+
+
+ public Map getDesignates()
+ {
+ return designates;
+ }
+
+
+ public void addDesignate( Designate designate )
+ {
+ if ( designate != null )
+ {
+ if ( designates == null )
+ {
+ designates = new HashMap();
+ }
+
+ designates.put( designate.getPid(), designate );
+ }
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaData.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaData.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,579 @@
+/*
+ * 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.metatype;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.felix.metatype.internal.Activator;
+import org.kxml2.io.KXmlParser;
+import org.osgi.service.log.LogService;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+
+/**
+ * The <code>MetaDataReader</code> provides two methods to read meta type
+ * documents according to the MetaType schema (105.8 XML Schema). The
+ * {@link #parse(URL)} and {@link #parse(InputStream)} methods may be called
+ * multiple times to parse such documents.
+ * <p>
+ * While reading the XML document java objects are created to hold the data.
+ * These objects are created by factory methods. Users of this may extend this
+ * class by overwriting the the factory methods to create specialized versions.
+ * One notable use of this is the extension of the {@link AD} class to overwrite
+ * the {@link AD#validate(String)} method. In this case, the {@link #createAD()}
+ * method would be overwritten to return an instance of the extending class.
+ * <p>
+ * This class is not thread safe. Using instances of this class in multiple
+ * threads concurrently is not supported and will fail.
+ *
+ * @author fmeschbe
+ */
+public class MetaDataReader
+{
+
+ /** The XML parser used to read the XML documents */
+ private KXmlParser parser = new KXmlParser();
+
+
+ /**
+ * Parses the XML document provided by the <code>url</code>. The XML document
+ * must be at the beginning of the stream contents.
+ * <p>
+ * This method is almost identical to
+ * <code>return parse(url.openStream());</code> but also sets the string
+ * representation of the URL as a location helper for error messages.
+ *
+ * @param url The <code>URL</code> providing access to the XML document.
+ *
+ * @return A {@link MetaData} providing access to the
+ * raw contents of the XML document.
+ *
+ * @throws IOException If an I/O error occurrs accessing the stream.
+ * @throws XmlPullParserException If an error occurrs parsing the XML
+ * document.
+ */
+ public MetaData parse( URL url ) throws IOException, XmlPullParserException
+ {
+ InputStream ins = null;
+ try
+ {
+ ins = url.openStream();
+ parser.setProperty( "http://xmlpull.org/v1/doc/properties.html#location", url.toString() );
+ return parse( ins );
+ }
+ finally
+ {
+ if ( ins != null )
+ {
+ try
+ {
+ ins.close();
+ }
+ catch ( IOException ioe )
+ {
+ // ignore
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Parses the XML document in the given input stream.
+ * <p>
+ * This method starts reading at the current position of the input stream
+ * and returns immediately after completely reading a single meta type
+ * document. The stream is not closed by this method.
+ *
+ * @param ins The <code>InputStream</code> providing the XML document
+ *
+ * @return A {@link MetaData} providing access to the
+ * raw contents of the XML document.
+ *
+ * @throws IOException If an I/O error occurrs accessing the stream.
+ * @throws XmlPullParserException If an error occurrs parsing the XML
+ * document.
+ */
+ public MetaData parse( InputStream ins ) throws IOException, XmlPullParserException
+ {
+ // set the parser input, use null encoding to force detection with <?xml?>
+ parser.setInput( ins, null );
+
+ MetaData mti = null;
+
+ int eventType = parser.getEventType();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "MetaData".equals( parser.getName() ) )
+ {
+ mti = readMetaData();
+ }
+ else
+ {
+ ignoreElement();
+ }
+ }
+ eventType = parser.next();
+ }
+
+ return mti;
+ }
+
+
+ private MetaData readMetaData() throws IOException, XmlPullParserException
+ {
+ MetaData mti = createMetaData();
+ mti.setLocalePrefix( getOptionalAttribute( "localization" ) );
+
+ int eventType = parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "OCD".equals( parser.getName() ) )
+ {
+ mti.addObjectClassDefinition( readOCD() );
+ }
+ else if ( "Designate".equals( parser.getName() ) )
+ {
+ mti.addDesignate( readDesignate() );
+ }
+ else
+ {
+ ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "MetaData".equals( parser.getName() ) )
+ {
+ break;
+ }
+
+ throw unexpectedElement();
+ }
+ eventType = parser.next();
+ }
+
+ return mti;
+ }
+
+
+ private OCD readOCD() throws IOException, XmlPullParserException
+ {
+ OCD ocd = createOCD();
+ ocd.setId( getRequiredAttribute( "id" ) );
+ ocd.setName( getRequiredAttribute( "name" ) );
+ ocd.setDescription( getOptionalAttribute( "description" ) );
+
+ int eventType = parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "AD".equals( parser.getName() ) )
+ {
+ ocd.addAttributeDefinition( readAD() );
+ }
+ else if ( "Icon".equals( parser.getName() ) )
+ {
+ String res = getRequiredAttribute( "resource" );
+ String sizeString = getRequiredAttribute( "size" );
+ try
+ {
+ Integer size = Integer.decode( sizeString );
+ ocd.addIcon( size, res );
+ }
+ catch ( NumberFormatException nfe )
+ {
+ Activator.log( LogService.LOG_DEBUG, "readOCD: Icon size '" + sizeString
+ + "' is not a valid number" );
+ }
+ }
+ else
+ {
+ ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "OCD".equals( parser.getName() ) )
+ {
+ break;
+ }
+ else if ( !"Icon".equals( parser.getName() ) )
+ {
+ throw unexpectedElement();
+ }
+ }
+ eventType = parser.next();
+ }
+
+ return ocd;
+ }
+
+
+ private Designate readDesignate() throws IOException, XmlPullParserException
+ {
+ Designate designate = createDesignate();
+ designate.setPid( getRequiredAttribute( "pid" ) );
+ designate.setFactoryPid( getOptionalAttribute( "factoryPid" ) );
+ designate.setBundleLocation( getOptionalAttribute( "bundle" ) );
+ designate.setOptional( getOptionalAttribute( "optional", false ) );
+ designate.setMerge( getOptionalAttribute( "merge", false ) );
+
+ int eventType = parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Object".equals( parser.getName() ) )
+ {
+ designate.setObject( readObject() );
+ }
+ else
+ {
+ ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "Designate".equals( parser.getName() ) )
+ {
+ break;
+ }
+
+ throw unexpectedElement();
+ }
+ eventType = parser.next();
+ }
+
+ return designate;
+ }
+
+
+ private AD readAD() throws IOException, XmlPullParserException
+ {
+ AD ad = createAD();
+ ad.setID( getRequiredAttribute( "id" ) );
+ ad.setName( getRequiredAttribute( "name" ) );
+ ad.setDescription( getOptionalAttribute( "description" ) );
+ ad.setType( getRequiredAttribute( "type" ) );
+ ad.setCardinality( getOptionalAttribute( "cardinality", 0 ) );
+ ad.setMin( getOptionalAttribute( "min" ) );
+ ad.setMax( getOptionalAttribute( "min" ) );
+ ad.setDefaultValue( getOptionalAttribute( "default" ) );
+ ad.setRequired( getOptionalAttribute( "required", true ) );
+
+ Map options = new LinkedHashMap();
+ int eventType = parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Option".equals( parser.getName() ) )
+ {
+ String value = getRequiredAttribute( "value" );
+ String label = getRequiredAttribute( "label" );
+ options.put( value, label );
+ }
+ else
+ {
+ ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "AD".equals( parser.getName() ) )
+ {
+ break;
+ }
+ else if ( !"Option".equals( parser.getName() ) )
+ {
+ throw unexpectedElement();
+ }
+ }
+ eventType = parser.next();
+ }
+
+ ad.setOptions( options );
+
+ return ad;
+ }
+
+
+ private DesignateObject readObject() throws IOException, XmlPullParserException
+ {
+ DesignateObject oh = createDesignateObject();
+ oh.setOcdRef( getRequiredAttribute( "ocdref" ) );
+
+ int eventType = parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Attribute".equals( parser.getName() ) )
+ {
+ oh.addAttribute( readAttribute() );
+ }
+ else
+ {
+ ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "Object".equals( parser.getName() ) )
+ {
+ break;
+ }
+ throw unexpectedElement();
+ }
+ eventType = parser.next();
+ }
+
+ return oh;
+ }
+
+
+ private Attribute readAttribute() throws IOException, XmlPullParserException
+ {
+ Attribute ah = createAttribute();
+ ah.setAdRef( getRequiredAttribute( "adref" ) );
+ ah.addContent( getOptionalAttribute( "content" ) );
+
+ int eventType = parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Value".equals( parser.getName() ) )
+ {
+ ah.addContent( parser.nextText() );
+ eventType = parser.getEventType();
+ continue;
+ }
+ else
+ {
+ ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "Attribute".equals( parser.getName() ) )
+ {
+ break;
+ }
+ else if ( !"Value".equals( parser.getName() ) )
+ {
+ throw unexpectedElement();
+ }
+ }
+ eventType = parser.next();
+ }
+
+ return ah;
+ }
+
+
+ //---------- Attribute access helper --------------------------------------
+
+ private String getRequiredAttribute( String attrName ) throws XmlPullParserException
+ {
+ String attrVal = parser.getAttributeValue( null, attrName );
+ if ( attrVal != null )
+ {
+ return attrVal;
+ }
+
+ // fail if value is missing
+ throw missingAttribute( attrName );
+ }
+
+
+ private String getOptionalAttribute( String attrName )
+ {
+ return getOptionalAttribute( attrName, ( String ) null );
+ }
+
+
+ private String getOptionalAttribute( String attrName, String defaultValue )
+ {
+ String attrVal = parser.getAttributeValue( null, attrName );
+ return ( attrVal != null ) ? attrVal : defaultValue;
+ }
+
+
+ private boolean getOptionalAttribute( String attrName, boolean defaultValue )
+ {
+ String attrVal = parser.getAttributeValue( null, attrName );
+ return ( attrVal != null ) ? "true".equalsIgnoreCase( attrVal ) : defaultValue;
+ }
+
+
+ private int getOptionalAttribute( String attrName, int defaultValue )
+ {
+ String attrVal = parser.getAttributeValue( null, attrName );
+ if ( attrVal != null && attrVal.length() > 0 )
+ {
+ try
+ {
+ return Integer.decode( attrVal ).intValue();
+ }
+ catch ( NumberFormatException nfe )
+ {
+ Activator.log( LogService.LOG_DEBUG, "getOptionalAttribute: Value '" + attrVal + "' of attribute "
+ + attrName + " is not a valid number. Using default value " + defaultValue );
+ }
+ }
+
+ // fallback to default
+ return defaultValue;
+ }
+
+
+ //---------- Error Handling support ---------------------------------------
+
+ private void ignoreElement() throws IOException, XmlPullParserException
+ {
+ String ignoredElement = parser.getName();
+
+ int depth = 0; // enable nested ignored elements
+ int eventType = parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( ignoredElement.equals( parser.getName() ) )
+ {
+ depth++;
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( ignoredElement.equals( parser.getName() ) )
+ {
+ if ( depth <= 0 )
+ {
+ return;
+ }
+
+ depth--;
+ }
+ }
+ eventType = parser.next();
+ }
+ }
+
+
+ private XmlPullParserException missingAttribute( String attrName )
+ {
+ String message = "Missing Attribute " + attrName + " in element " + parser.getName();
+ return new XmlPullParserException( message, parser, null );
+ }
+
+
+ private XmlPullParserException unexpectedElement()
+ {
+ String message = "Illegal Element " + parser.getName();
+ return new XmlPullParserException( message, parser, null );
+ }
+
+
+ //---------- Factory methods ----------------------------------------------
+
+ /**
+ * Creates a new {@link MetaData} object to hold the contents of the
+ * <code>MetaData</code> element.
+ * <p>
+ * This method may be overwritten to return a customized extension.
+ */
+ protected MetaData createMetaData()
+ {
+ return new MetaData();
+ }
+
+
+ /**
+ * Creates a new {@link OCD} object to hold the contents of the
+ * <code>OCD</code> element.
+ * <p>
+ * This method may be overwritten to return a customized extension.
+ */
+ protected OCD createOCD()
+ {
+ return new OCD();
+ }
+
+
+ /**
+ * Creates a new {@link AD} object to hold the contents of the
+ * <code>AD</code> element.
+ * <p>
+ * This method may be overwritten to return a customized extension.
+ */
+ protected AD createAD()
+ {
+ return new AD();
+ }
+
+
+ /**
+ * Creates a new {@link DesignateObject} object to hold the contents of the
+ * <code>Object</code> element.
+ * <p>
+ * This method may be overwritten to return a customized extension.
+ */
+ protected DesignateObject createDesignateObject()
+ {
+ return new DesignateObject();
+ }
+
+
+ /**
+ * Creates a new {@link Attribute} object to hold the contents of the
+ * <code>Attribute</code> element.
+ * <p>
+ * This method may be overwritten to return a customized extension.
+ */
+ protected Attribute createAttribute()
+ {
+ return new Attribute();
+ }
+
+
+ /**
+ * Creates a new {@link Designate} object to hold the contents of the
+ * <code>Designate</code> element.
+ * <p>
+ * This method may be overwritten to return a customized extension.
+ */
+ protected Designate createDesignate()
+ {
+ return new Designate();
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/MetaDataReader.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/OCD.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/OCD.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/OCD.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/OCD.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,123 @@
+/*
+ * 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.metatype;
+
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+
+/**
+ * The <code>OCD</code> class represents the <code>OCD</code> element of the
+ * meta type descriptor.
+ *
+ * @author fmeschbe
+ */
+public class OCD
+{
+
+ private String id;
+ private String name;
+ private String description;
+ private Map attributes;
+ private Map icons;
+
+
+ public String getID()
+ {
+ return id;
+ }
+
+
+ public void setId( String id )
+ {
+ this.id = id;
+ }
+
+
+ public String getName()
+ {
+ return name;
+ }
+
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+
+ public void setDescription( String description )
+ {
+ this.description = description;
+ }
+
+
+ public Map getIcons()
+ {
+ return icons;
+ }
+
+
+ /**
+ *
+ * @param size
+ * @param icon The icon, either an URL or a string designating a resource
+ * which may be a localized string
+ */
+ public void addIcon( Integer size, String icon )
+ {
+ if ( icon != null )
+ {
+ if ( icons == null )
+ {
+ icons = new HashMap();
+ }
+
+ icons.put( size, icon );
+ }
+ }
+
+
+ public Map getAttributeDefinitions()
+ {
+ return attributes;
+ }
+
+
+ public void addAttributeDefinition( AD attribute )
+ {
+ if ( attribute != null )
+ {
+ if ( attributes == null )
+ {
+ attributes = new LinkedHashMap();
+ }
+
+ attributes.put( attribute.getID(), attribute );
+ }
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/OCD.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/OCD.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/Activator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/Activator.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/Activator.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/Activator.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,247 @@
+/*
+ * 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.metatype.internal;
+
+
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import org.apache.felix.metatype.internal.l10n.BundleResources;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+import org.osgi.service.metatype.MetaTypeService;
+import org.osgi.util.tracker.ServiceTracker;
+
+
+/**
+ * The <code>Activator</code> class is the <code>BundleActivator</code> of
+ * this bundle and provides abstract logging functionality: If a
+ * <code>LogService</code> is available, that service is used, otherwise
+ * logging goes to standard output or standard error (in case of level ERROR
+ * messages).
+ *
+ * @author fmeschbe
+ */
+public class Activator implements BundleActivator
+{
+
+ /** The name of the log service. */
+ private static final String NAME_LOG_SERVICE = LogService.class.getName();
+
+ /**
+ * A <code>SimpleDateFormat</code> object to format the a log message time
+ * stamp in case of logging to standard output/error (value of format
+ * pattern is "dd.MM.yyyy HH:mm:ss").
+ */
+ private static final SimpleDateFormat FORMAT = new SimpleDateFormat( "dd.MM.yyyy HH:mm:ss" );
+
+ /**
+ * The (singleton) instance of this activator. Used by the log methods to
+ * access the {@link #logService} field.
+ */
+ private static Activator INSTANCE;
+
+ /**
+ * The <code>LogService</code> used to log messages. If a log service is
+ * not available in the framework, this field is <code>null</code>.
+ *
+ * @see #start(BundleContext)
+ * @see #serviceChanged(ServiceEvent)
+ */
+ private ServiceTracker logService;
+
+ /*
+ * Set the static INSTANCE field to this new instance
+ */
+ {
+ INSTANCE = this;
+ }
+
+
+ /**
+ * Starts this bundle doing the following:
+ * <ol>
+ * <li>Register as listener for service events concerning the
+ * <code>LogService</code> (see {@link #serviceChanged(ServiceEvent)}
+ * <li>Try to get the <code>LogService</code>
+ * <li>Registers the <code>MetaTypeService</code> implementation provided
+ * by this bundle.
+ * </ol>
+ *
+ * @param context The <code>BundleContext</code> of this activator's bundle
+ */
+ public void start( BundleContext context )
+ {
+ // register for log service events
+ logService = new ServiceTracker( context, NAME_LOG_SERVICE, null );
+ logService.open();
+
+ // register the MetaTypeService now, that we are ready
+ Dictionary props = new Hashtable();
+ props.put( Constants.SERVICE_PID, "org.apache.felix.metatype.MetaTypeService" );
+ props.put( Constants.SERVICE_DESCRIPTION, "MetaTypeService Specification 1.1 Implementation" );
+ props.put( Constants.SERVICE_VENDOR, "Apache Software Foundation" );
+ MetaTypeService metaTypeService = new MetaTypeServiceImpl( context );
+ context.registerService( MetaTypeService.class.getName(), metaTypeService, props );
+ }
+
+
+ /**
+ * Stops this bundle by just unregistering as a service listener.
+ * <p>
+ * The framework will take care of ungetting the <code>LogService</code> and
+ * unregistering the <code>MetaTypeService</code> registered by the
+ * {@link #start(BundleContext)} method.
+ *
+ * @param context The <code>BundleContext</code> of this activator's bundle
+ */
+ public void stop( BundleContext context )
+ {
+ logService.close();
+
+ // make sure the static BundleResources cache does not block the class laoder
+ BundleResources.clearResourcesCache();
+ }
+
+ //---------- Logging Support ----------------------------------------------
+ // log to stdout or use LogService
+
+ public static void log( int level, String message )
+ {
+ LogService log = ( LogService ) INSTANCE.logService.getService();
+ if ( log == null )
+ {
+ _log( null, level, message, null );
+ }
+ else
+ {
+ log.log( level, message );
+ }
+ }
+
+
+ public static void log( int level, String message, Throwable exception )
+ {
+ LogService log = ( LogService ) INSTANCE.logService.getService();
+ if ( log == null )
+ {
+ _log( null, level, message, exception );
+ }
+ else
+ {
+ log.log( level, message, exception );
+ }
+ }
+
+
+ public static void log( ServiceReference sr, int level, String message )
+ {
+ LogService log = ( LogService ) INSTANCE.logService.getService();
+ if ( log == null )
+ {
+ _log( sr, level, message, null );
+ }
+ else
+ {
+ log.log( sr, level, message );
+ }
+ }
+
+
+ public static void log( ServiceReference sr, int level, String message, Throwable exception )
+ {
+ LogService log = ( LogService ) INSTANCE.logService.getService();
+ if ( log == null )
+ {
+ _log( sr, level, message, exception );
+ }
+ else
+ {
+ log.log( sr, level, message, exception );
+ }
+ }
+
+
+ //---------- Helper Methods -----------------------------------------------
+
+ private static void _log( ServiceReference sr, int level, String message, Throwable exception )
+ {
+ String time = getTimeStamp();
+
+ StringBuffer buf = new StringBuffer( time );
+ buf.append( ' ' ).append( toLevelString( level ) ).append( ' ' );
+ buf.append( message );
+
+ if ( sr != null )
+ {
+ String name = ( String ) sr.getProperty( Constants.SERVICE_PID );
+ if ( name == null )
+ {
+ name = ( ( String[] ) sr.getProperty( Constants.OBJECTCLASS ) )[0];
+ }
+ buf.append( " (" ).append( name ).append( ", service.id=" ).append( sr.getProperty( Constants.SERVICE_ID ) )
+ .append( ')' );
+ }
+
+ PrintStream dst = ( level == LogService.LOG_ERROR ) ? System.err : System.out;
+ dst.println( buf );
+
+ if ( exception != null )
+ {
+ buf = new StringBuffer( time );
+ buf.append( ' ' ).append( toLevelString( level ) ).append( ' ' );
+ dst.print( buf );
+ exception.printStackTrace( dst );
+ }
+ }
+
+
+ private static String getTimeStamp()
+ {
+ synchronized ( FORMAT )
+ {
+ return FORMAT.format( new Date() );
+ }
+ }
+
+
+ private static String toLevelString( int level )
+ {
+ switch ( level )
+ {
+ case LogService.LOG_DEBUG:
+ return "*DEBUG*";
+ case LogService.LOG_INFO:
+ return "*INFO *";
+ case LogService.LOG_WARNING:
+ return "*WARN *";
+ case LogService.LOG_ERROR:
+ return "*ERROR*";
+ default:
+ return "*" + level + "*";
+ }
+
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/Activator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/Activator.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,151 @@
+/*
+ * 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.metatype.internal;
+
+
+import org.apache.felix.metatype.AD;
+import org.apache.felix.metatype.internal.l10n.Resources;
+import org.osgi.service.metatype.AttributeDefinition;
+
+
+/**
+ * The <code>LocalizedAttributeDefinition</code> class is the implementation
+ * of the <code>AttributeDefinition</code> interface. This class delegates
+ * calls to the underlying {@link AD} localizing the results of the following
+ * methods: {@link #getName()}, {@link #getDescription()},
+ * {@link #getOptionLabels()}, and {@link #validate(String)}.
+ *
+ * @author fmeschbe
+ */
+class LocalizedAttributeDefinition extends LocalizedBase implements AttributeDefinition
+{
+
+ private final AD ad;
+
+
+ /**
+ * Creates and instance of this localizing facade.
+ *
+ * @param ad The {@link AD} to which calls are delegated.
+ * @param resources The {@link Resources} used to localize return values of
+ * localizable methods.
+ */
+ LocalizedAttributeDefinition( AD ad, Resources resources )
+ {
+ super( resources );
+ this.ad = ad;
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getCardinality()
+ */
+ public int getCardinality()
+ {
+ return ad.getCardinality();
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getDefaultValue()
+ */
+ public String[] getDefaultValue()
+ {
+ return ad.getDefaultValue();
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getDescription()
+ */
+ public String getDescription()
+ {
+ return localize( ad.getDescription() );
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getID()
+ */
+ public String getID()
+ {
+ return ad.getID();
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getName()
+ */
+ public String getName()
+ {
+ return localize( ad.getName() );
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getOptionLabels()
+ */
+ public String[] getOptionLabels()
+ {
+ return localize( ad.getOptionLabels() );
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getOptionValues()
+ */
+ public String[] getOptionValues()
+ {
+ return ad.getOptionValues();
+ }
+
+
+ /**
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#getType()
+ */
+ public int getType()
+ {
+ return ad.getType();
+ }
+
+
+ /**
+ * @param value
+ * @return
+ * @see org.osgi.service.metatype.AttributeDefinition#validate(java.lang.String)
+ */
+ public String validate( String value )
+ {
+ String message = ad.validate( value );
+ if ( message == null || message.length() == 0 )
+ {
+ return message;
+ }
+
+ return localize( message );
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url
Added: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedBase.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedBase.java?view=auto&rev=527597
==============================================================================
--- incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedBase.java (added)
+++ incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedBase.java Wed Apr 11 11:27:12 2007
@@ -0,0 +1,166 @@
+/*
+ * 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.metatype.internal;
+
+
+import org.apache.felix.metatype.internal.l10n.Resources;
+import org.osgi.service.log.LogService;
+
+
+/**
+ * The <code>LocalizedBase</code> class provides methods to localize strings
+ * and string arrays on demand using a <code>ResourceBundle</code> specified
+ * at construction time.
+ *
+ * @author fmeschbe
+ */
+abstract class LocalizedBase
+{
+
+ /**
+ * The {@link Resources} used to localize strings.
+ *
+ * @see #localize(String)
+ * @see #localize(String[])
+ */
+ private final Resources resources;
+
+
+ /**
+ * Sets up this class using the given <code>ResourceBundle</code>.
+ *
+ * @param resources The {@link Resources} used to localize return values of
+ * localizable methods.
+ *
+ * @throws NullPointerException If <code>resources</code> is
+ * <code>null</code>.
+ */
+ protected LocalizedBase( Resources resources )
+ {
+ if ( resources == null )
+ {
+ throw new NullPointerException( "resources" );
+ }
+ this.resources = resources;
+ }
+
+
+ /**
+ * Returns the {@link Resources} assigned to this instance.
+ */
+ protected Resources getResources()
+ {
+ return resources;
+ }
+
+
+ /**
+ * Calls {@link #localize(String)} for each string in the array and returns
+ * an array of the resulting localized strings. If <code>strings</code> is
+ * <code>null</code> <code>null</code> is returned.
+ *
+ * @param strings An array of non-<code>null</code> strings to localize.
+ *
+ * @return <code>null</code> if <code>strings</code> is <code>null</code> or
+ * an array of the same size as the <code>strings</code> array
+ * containing localized strings.
+ */
+ protected String[] localize( String[] strings )
+ {
+ if ( strings == null )
+ {
+ return null;
+ }
+
+ String[] localized = new String[strings.length];
+ for ( int i = 0; i < strings.length; i++ )
+ {
+ localized[i] = localize( strings[i] );
+ }
+ return localized;
+ }
+
+
+ /**
+ * Localizes the string using the
+ * {@link #getResourceBundle() ResourceBundle} set on this instance if
+ * string starts with the percent character (<code>%</code>). If the
+ * string is <code>null</code>, does not start with a percent character
+ * or the resource whose key is the string without the leading the percent
+ * character is not found the string is returned without the leading percent
+ * character.
+ * <p>
+ * Examples of different localizations:
+ * <p>
+ * <table border="0" cellspacing="0" cellpadding="3">
+ * <tr bgcolor="#ccccff">
+ * <th><code>string</code></th>
+ * <th>Key</th>
+ * <th>Resource</th>
+ * <th>Result</th>
+ * </tr>
+ * <tr>
+ * <td><code>null</code></td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td><code>null</code></td>
+ * </tr>
+ * <tr bgcolor="#eeeeff">
+ * <td>sample</td>
+ * <td>-</td>
+ * <td>-</td>
+ * <td>sample</td>
+ * </tr>
+ * <tr>
+ * <td><b>%</b>sample</td>
+ * <td>sample</td>
+ * <td>-</td>
+ * <td>sample</td>
+ * </tr>
+ * <tr bgcolor="#eeeeff">
+ * <td><b>%</b>sample</td>
+ * <td>sample</td>
+ * <td>resource</td>
+ * <td>resource</td>
+ * </tr>
+ * </table>
+ *
+ * @param string The string to localize
+ * @return The localized string
+ */
+ protected String localize( String string )
+ {
+ if ( string != null && string.startsWith( "%" ) )
+ {
+ string = string.substring( 1 );
+ try
+ {
+ return getResources().getResource( string );
+ }
+ catch ( Exception e )
+ {
+ // ClassCastException, MissingResourceException
+ Activator.log( LogService.LOG_DEBUG, "localize: Failed getting resource '" + string + "'", e );
+ }
+ }
+
+ // just return the string unmodified
+ return string;
+ }
+}
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedBase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/felix/trunk/metatype/src/main/java/org/apache/felix/metatype/internal/LocalizedBase.java
------------------------------------------------------------------------------
svn:keywords = author date id revision url