You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2009/06/27 17:53:26 UTC
svn commit: r788992 [17/25] - in /incubator/ace/trunk: gateway/ gateway/src/
gateway/src/net/ gateway/src/net/luminis/ gateway/src/net/luminis/liq/
gateway/src/net/luminis/liq/bootstrap/
gateway/src/net/luminis/liq/bootstrap/multigateway/ gateway/src/n...
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/AD.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/AD.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/AD.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/AD.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,477 @@
+/*
+ * 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.*;
+
+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 typeString 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 options the options 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));
+ }
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/Attribute.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/Attribute.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/Attribute.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/Attribute.java Sat Jun 27 15:53:04 2009
@@ -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: 2007-04-11 20:27:12 +0200 (Wed, 11 Apr 2007) $
+ */
+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 ) );
+ }
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/DefaultMetaTypeProvider.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/DefaultMetaTypeProvider.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/DefaultMetaTypeProvider.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/DefaultMetaTypeProvider.java Sat Jun 27 15:53:04 2009
@@ -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;
+ }
+
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/Designate.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/Designate.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/Designate.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/Designate.java Sat Jun 27 15:53:04 2009
@@ -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;
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/DesignateObject.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/DesignateObject.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/DesignateObject.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/DesignateObject.java Sat Jun 27 15:53:04 2009
@@ -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 );
+ }
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaData.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaData.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaData.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaData.java Sat Jun 27 15:53:04 2009
@@ -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 );
+ }
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaDataReader.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaDataReader.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaDataReader.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/MetaDataReader.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,577 @@
+/*
+ * 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();
+ this.parser.setProperty( "http://xmlpull.org/v1/doc/properties.html#location", url.toString() );
+ this.parser.setFeature(KXmlParser.FEATURE_PROCESS_NAMESPACES, true);
+ return this.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?>
+ this.parser.setInput( ins, null );
+
+ MetaData mti = null;
+
+ int eventType = this.parser.getEventType();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "MetaData".equals( this.parser.getName() ) )
+ {
+ mti = this.readMetaData();
+ }
+ else
+ {
+ this.ignoreElement();
+ }
+ }
+ eventType = this.parser.next();
+ }
+
+ return mti;
+ }
+
+
+ private MetaData readMetaData() throws IOException, XmlPullParserException
+ {
+ MetaData mti = this.createMetaData();
+ mti.setLocalePrefix( this.getOptionalAttribute( "localization" ) );
+
+ int eventType = this.parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "OCD".equals( this.parser.getName() ) )
+ {
+ mti.addObjectClassDefinition( this.readOCD() );
+ }
+ else if ( "Designate".equals( this.parser.getName() ) )
+ {
+ mti.addDesignate( this.readDesignate() );
+ }
+ else
+ {
+ this.ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "MetaData".equals( this.parser.getName() ) )
+ {
+ break;
+ }
+
+ throw this.unexpectedElement();
+ }
+ eventType = this.parser.next();
+ }
+
+ return mti;
+ }
+
+
+ private OCD readOCD() throws IOException, XmlPullParserException
+ {
+ OCD ocd = this.createOCD();
+ ocd.setId( this.getRequiredAttribute( "id" ) );
+ ocd.setName( this.getRequiredAttribute( "name" ) );
+ ocd.setDescription( this.getOptionalAttribute( "description" ) );
+
+ int eventType = this.parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "AD".equals( this.parser.getName() ) )
+ {
+ ocd.addAttributeDefinition( this.readAD() );
+ }
+ else if ( "Icon".equals( this.parser.getName() ) )
+ {
+ String res = this.getRequiredAttribute( "resource" );
+ String sizeString = this.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
+ {
+ this.ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "OCD".equals( this.parser.getName() ) )
+ {
+ break;
+ }
+ else if ( !"Icon".equals( this.parser.getName() ) )
+ {
+ throw this.unexpectedElement();
+ }
+ }
+ eventType = this.parser.next();
+ }
+
+ return ocd;
+ }
+
+
+ private Designate readDesignate() throws IOException, XmlPullParserException
+ {
+ Designate designate = this.createDesignate();
+ designate.setPid( this.getRequiredAttribute( "pid" ) );
+ designate.setFactoryPid( this.getOptionalAttribute( "factoryPid" ) );
+ designate.setBundleLocation( this.getOptionalAttribute( "bundle" ) );
+ designate.setOptional( this.getOptionalAttribute( "optional", false ) );
+ designate.setMerge( this.getOptionalAttribute( "merge", false ) );
+
+ int eventType = this.parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Object".equals( this.parser.getName() ) )
+ {
+ designate.setObject( this.readObject() );
+ }
+ else
+ {
+ this.ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "Designate".equals( this.parser.getName() ) )
+ {
+ break;
+ }
+
+ throw this.unexpectedElement();
+ }
+ eventType = this.parser.next();
+ }
+
+ return designate;
+ }
+
+
+ private AD readAD() throws IOException, XmlPullParserException
+ {
+ AD ad = this.createAD();
+ ad.setID( this.getRequiredAttribute( "id" ) );
+ ad.setName( this.getOptionalAttribute( "name" ) );
+ ad.setDescription( this.getOptionalAttribute( "description" ) );
+ ad.setType( this.getRequiredAttribute( "type" ) );
+ ad.setCardinality( this.getOptionalAttribute( "cardinality", 0 ) );
+ ad.setMin( this.getOptionalAttribute( "min" ) );
+ ad.setMax( this.getOptionalAttribute( "min" ) );
+ ad.setDefaultValue( this.getOptionalAttribute( "default" ) );
+ ad.setRequired( this.getOptionalAttribute( "required", true ) );
+
+ Map options = new LinkedHashMap();
+ int eventType = this.parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Option".equals( this.parser.getName() ) )
+ {
+ String value = this.getRequiredAttribute( "value" );
+ String label = this.getRequiredAttribute( "label" );
+ options.put( value, label );
+ }
+ else
+ {
+ this.ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "AD".equals( this.parser.getName() ) )
+ {
+ break;
+ }
+ else if ( !"Option".equals( this.parser.getName() ) )
+ {
+ throw this.unexpectedElement();
+ }
+ }
+ eventType = this.parser.next();
+ }
+
+ ad.setOptions( options );
+
+ return ad;
+ }
+
+
+ private DesignateObject readObject() throws IOException, XmlPullParserException
+ {
+ DesignateObject oh = this.createDesignateObject();
+ oh.setOcdRef( this.getRequiredAttribute( "ocdref" ) );
+
+ int eventType = this.parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Attribute".equals( this.parser.getName() ) )
+ {
+ oh.addAttribute( this.readAttribute() );
+ }
+ else
+ {
+ this.ignoreElement();
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "Object".equals( this.parser.getName() ) )
+ {
+ break;
+ }
+ throw this.unexpectedElement();
+ }
+ eventType = this.parser.next();
+ }
+
+ return oh;
+ }
+
+
+ private Attribute readAttribute() throws IOException, XmlPullParserException
+ {
+ Attribute ah = this.createAttribute();
+ ah.setAdRef( this.getRequiredAttribute( "adref" ) );
+ ah.addContent( this.getOptionalAttribute( "content" ) );
+
+ int eventType = this.parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( "Value".equals( this.parser.getName() ) )
+ {
+ ah.addContent( this.parser.nextText() );
+ eventType = this.parser.getEventType();
+ continue;
+ }
+ this.ignoreElement();
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( "Attribute".equals( this.parser.getName() ) )
+ {
+ break;
+ }
+ else if ( !"Value".equals( this.parser.getName() ) )
+ {
+ throw this.unexpectedElement();
+ }
+ }
+ eventType = this.parser.next();
+ }
+
+ return ah;
+ }
+
+
+ //---------- Attribute access helper --------------------------------------
+
+ private String getRequiredAttribute( String attrName ) throws XmlPullParserException
+ {
+ String attrVal = this.parser.getAttributeValue( null, attrName );
+ if ( attrVal != null )
+ {
+ return attrVal;
+ }
+
+ // fail if value is missing
+ throw this.missingAttribute( attrName );
+ }
+
+
+ private String getOptionalAttribute( String attrName )
+ {
+ return this.getOptionalAttribute( attrName, ( String ) null );
+ }
+
+
+ private String getOptionalAttribute( String attrName, String defaultValue )
+ {
+ String attrVal = this.parser.getAttributeValue( null, attrName );
+ return ( attrVal != null ) ? attrVal : defaultValue;
+ }
+
+
+ private boolean getOptionalAttribute( String attrName, boolean defaultValue )
+ {
+ String attrVal = this.parser.getAttributeValue( null, attrName );
+ return ( attrVal != null ) ? "true".equalsIgnoreCase( attrVal ) : defaultValue;
+ }
+
+
+ private int getOptionalAttribute( String attrName, int defaultValue )
+ {
+ String attrVal = this.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 = this.parser.getName();
+
+ int depth = 0; // enable nested ignored elements
+ int eventType = this.parser.next();
+ while ( eventType != XmlPullParser.END_DOCUMENT )
+ {
+ if ( eventType == XmlPullParser.START_TAG )
+ {
+ if ( ignoredElement.equals( this.parser.getName() ) )
+ {
+ depth++;
+ }
+ }
+ else if ( eventType == XmlPullParser.END_TAG )
+ {
+ if ( ignoredElement.equals( this.parser.getName() ) )
+ {
+ if ( depth <= 0 )
+ {
+ return;
+ }
+
+ depth--;
+ }
+ }
+ eventType = this.parser.next();
+ }
+ }
+
+
+ private XmlPullParserException missingAttribute( String attrName )
+ {
+ String message = "Missing Attribute " + attrName + " in element " + this.parser.getName();
+ return new XmlPullParserException( message, this.parser, null );
+ }
+
+
+ private XmlPullParserException unexpectedElement()
+ {
+ String message = "Illegal Element " + this.parser.getName();
+ return new XmlPullParserException( message, this.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();
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/OCD.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/OCD.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/OCD.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/OCD.java Sat Jun 27 15:53:04 2009
@@ -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 );
+ }
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/Activator.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/Activator.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/Activator.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/Activator.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,242 @@
+/*
+ * 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.*;
+
+import org.apache.felix.metatype.internal.l10n.BundleResources;
+import org.osgi.framework.*;
+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>
+ * <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 + "*";
+ }
+
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedAttributeDefinition.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,142 @@
+/*
+ * 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;
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getCardinality()
+ */
+ public int getCardinality()
+ {
+ return ad.getCardinality();
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getDefaultValue()
+ */
+ public String[] getDefaultValue()
+ {
+ return ad.getDefaultValue();
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getDescription()
+ */
+ public String getDescription()
+ {
+ return localize( ad.getDescription() );
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getID()
+ */
+ public String getID()
+ {
+ return ad.getID();
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getName()
+ */
+ public String getName()
+ {
+ return localize( ad.getName() );
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getOptionLabels()
+ */
+ public String[] getOptionLabels()
+ {
+ return localize( ad.getOptionLabels() );
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getOptionValues()
+ */
+ public String[] getOptionValues()
+ {
+ return ad.getOptionValues();
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.AttributeDefinition#getType()
+ */
+ public int getType()
+ {
+ return ad.getType();
+ }
+
+
+ /**
+ * @param value
+ * @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 );
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedBase.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedBase.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedBase.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedBase.java Sat Jun 27 15:53:04 2009
@@ -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;
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedObjectClassDefinition.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedObjectClassDefinition.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedObjectClassDefinition.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/LocalizedObjectClassDefinition.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,251 @@
+/*
+ * 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.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+
+import org.apache.felix.metatype.AD;
+import org.apache.felix.metatype.OCD;
+import org.apache.felix.metatype.internal.l10n.Resources;
+import org.osgi.framework.Bundle;
+import org.osgi.service.metatype.AttributeDefinition;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+
+/**
+ * The <code>LocalizedObjectClassDefinition</code> class is the implementation
+ * of the <code>ObjectClassDefinition</code> interface. This class delegates
+ * calls to the underlying {@link OCD} localizing the results of the following
+ * methods: {@link #getName()}, {@link #getDescription()}, and
+ * {@link #getIcon(int)}.
+ *
+ * @author fmeschbe
+ */
+public class LocalizedObjectClassDefinition extends LocalizedBase implements ObjectClassDefinition
+{
+
+ private Bundle bundle;
+
+ private OCD ocd;
+
+
+ /**
+ * Creates and instance of this localizing facade.
+ *
+ * @param bundle The <code>Bundle</code> providing this object class
+ * definition.
+ * @param ocd The {@link OCD} to which calls are delegated.
+ * @param resources The {@link Resources} used to localize return values of
+ * localizable methods.
+ */
+ public LocalizedObjectClassDefinition( Bundle bundle, OCD ocd, Resources resources )
+ {
+ super( resources );
+ this.bundle = bundle;
+ this.ocd = ocd;
+ }
+
+
+ /**
+ * @param filter
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getAttributeDefinitions(int)
+ */
+ public AttributeDefinition[] getAttributeDefinitions( int filter )
+ {
+ if ( ocd.getAttributeDefinitions() == null )
+ {
+ return null;
+ }
+
+ Iterator adhIter = ocd.getAttributeDefinitions().values().iterator();
+ if ( filter == ObjectClassDefinition.OPTIONAL || filter == ObjectClassDefinition.REQUIRED )
+ {
+ boolean required = ( filter == ObjectClassDefinition.REQUIRED );
+ adhIter = new RequiredFilterIterator( adhIter, required );
+ }
+ else if ( filter != ObjectClassDefinition.ALL )
+ {
+ return null;
+ }
+
+ if ( !adhIter.hasNext() )
+ {
+ return null;
+ }
+
+ List result = new ArrayList();
+ while ( adhIter.hasNext() )
+ {
+ result.add( new LocalizedAttributeDefinition( ( AD ) adhIter.next(), getResources() ) );
+ }
+
+ return ( AttributeDefinition[] ) result.toArray( new AttributeDefinition[result.size()] );
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getDescription()
+ */
+ public String getDescription()
+ {
+ return localize( ocd.getDescription() );
+ }
+
+
+ /**
+ * @param size
+ * @throws IOException
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getIcon(int)
+ */
+ public InputStream getIcon( int size ) throws IOException
+ {
+ // nothing if no icons are defined
+ Map icons = ocd.getIcons();
+ if ( icons == null )
+ {
+ return null;
+ }
+
+ // get exact size
+ String iconPath = ( String ) icons.get( new Integer( size ) );
+ if ( iconPath == null )
+ {
+ // approximate size: largest icon smaller than requested
+ Integer selected = new Integer( Integer.MIN_VALUE );
+ for ( Iterator ei = icons.keySet().iterator(); ei.hasNext(); )
+ {
+ Map.Entry entry = ( Map.Entry ) ei.next();
+ Integer keySize = ( Integer ) entry.getKey();
+ if ( keySize.intValue() <= size && selected.compareTo( keySize ) < 0 )
+ {
+ selected = keySize;
+ }
+ }
+ // get the raw path, fail if no path can be found
+ iconPath = ( String ) icons.get( selected );
+ }
+
+ // fail if no icon could be found
+ if ( iconPath == null )
+ {
+ return null;
+ }
+
+ // localize the path
+ iconPath = localize( iconPath );
+
+ // try to resolve the path in the bundle
+ URL url = bundle.getEntry( iconPath );
+ if ( url == null )
+ {
+ return null;
+ }
+
+ // open the stream on the URL - this may throw an IOException
+ return url.openStream();
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getID()
+ */
+ public String getID()
+ {
+ return ocd.getID();
+ }
+
+
+ /**
+ * @see org.osgi.service.metatype.ObjectClassDefinition#getName()
+ */
+ public String getName()
+ {
+ return localize( ocd.getName() );
+ }
+
+ private static class RequiredFilterIterator implements Iterator
+ {
+
+ private final Iterator base;
+
+ private final boolean required;
+
+ private AD next;
+
+
+ private RequiredFilterIterator( Iterator base, boolean required )
+ {
+ this.base = base;
+ this.required = required;
+ this.next = seek();
+ }
+
+
+ public boolean hasNext()
+ {
+ return next != null;
+ }
+
+
+ public Object next()
+ {
+ if ( !hasNext() )
+ {
+ throw new NoSuchElementException();
+ }
+
+ AD toReturn = next;
+ next = seek();
+ return toReturn;
+ }
+
+
+ public void remove()
+ {
+ throw new UnsupportedOperationException( "remove" );
+ }
+
+
+ private AD seek()
+ {
+ if ( base.hasNext() )
+ {
+ AD next;
+ do
+ {
+ next = ( AD ) base.next();
+ }
+ while ( next.isRequired() != required && base.hasNext() );
+
+ if ( next.isRequired() == required )
+ {
+ return next;
+ }
+ }
+
+ // nothing found any more
+ return null;
+ }
+
+ }
+}
Added: incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/MetaTypeInformationImpl.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/MetaTypeInformationImpl.java?rev=788992&view=auto
==============================================================================
--- incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/MetaTypeInformationImpl.java (added)
+++ incubator/ace/trunk/server/src/org/apache/felix/metatype/internal/MetaTypeInformationImpl.java Sat Jun 27 15:53:04 2009
@@ -0,0 +1,214 @@
+/*
+ * 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.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.felix.metatype.DefaultMetaTypeProvider;
+import org.apache.felix.metatype.Designate;
+import org.apache.felix.metatype.DesignateObject;
+import org.apache.felix.metatype.MetaData;
+import org.apache.felix.metatype.OCD;
+import org.osgi.framework.Bundle;
+import org.osgi.service.metatype.MetaTypeInformation;
+import org.osgi.service.metatype.MetaTypeProvider;
+import org.osgi.service.metatype.ObjectClassDefinition;
+
+/**
+ * The <code>MetaTypeInformationImpl</code> class implements the
+ * <code>MetaTypeInformation</code> interface returned from the
+ * <code>MetaTypeService</code>.
+ *
+ * @author fmeschbe
+ */
+public class MetaTypeInformationImpl implements MetaTypeInformation {
+
+ // also defined in org.osgi.service.cm.ConfigurationAdmin, but copied
+ // here to not create a synthetic dependency
+ public static final String SERVICE_FACTORYPID = "service.factoryPid";
+
+ private final Bundle bundle;
+
+ private Set pids;
+
+ private Set factoryPids;
+
+ private Set locales;
+
+ private Map metaTypeProviders;
+
+ protected MetaTypeInformationImpl(Bundle bundle) {
+ this.bundle = bundle;
+ this.pids = new TreeSet();
+ this.factoryPids = new TreeSet();
+ this.metaTypeProviders = new HashMap();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeInformation#getBundle()
+ */
+ public Bundle getBundle() {
+ return this.bundle;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeInformation#getFactoryPids()
+ */
+ public String[] getFactoryPids() {
+ return (String[]) this.factoryPids.toArray(new String[this.factoryPids.size()]);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeInformation#getPids()
+ */
+ public String[] getPids() {
+ return (String[]) this.pids.toArray(new String[this.pids.size()]);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeProvider#getLocales()
+ */
+ public String[] getLocales() {
+ if (this.locales == null) {
+ synchronized (this) {
+ Set newLocales = new TreeSet();
+ for (Iterator mi = this.metaTypeProviders.values().iterator(); mi.hasNext();) {
+ MetaTypeProvider mtp = (MetaTypeProvider) mi.next();
+ this.addValues(newLocales, mtp.getLocales());
+ }
+ this.locales = newLocales;
+ }
+ }
+
+ return (String[]) this.locales.toArray(new String[this.locales.size()]);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.osgi.service.metatype.MetaTypeProvider#getObjectClassDefinition(java.lang.String,
+ * java.lang.String)
+ */
+ public ObjectClassDefinition getObjectClassDefinition(String id,
+ String locale) {
+ MetaTypeProvider mtp = (MetaTypeProvider) this.metaTypeProviders.get(id);
+ return (mtp != null) ? mtp.getObjectClassDefinition(id, locale) : null;
+ }
+
+ // ---------- internal support for metadata -------------------------------
+
+ Designate getDesignate( String pid )
+ {
+ Object mto = this.metaTypeProviders.get( pid );
+ if ( mto instanceof DefaultMetaTypeProvider )
+ {
+ return ( ( DefaultMetaTypeProvider ) mto ).getDesignate( pid );
+ }
+
+ return null;
+ }
+
+ // ---------- setters to fill the values -----------------------------------
+
+ protected void addMetaData(MetaData md) {
+ if (md.getDesignates() != null) {
+ // meta type provide to register by PID
+ DefaultMetaTypeProvider dmtp = new DefaultMetaTypeProvider(this.bundle, md);
+
+ Iterator designates = md.getDesignates().values().iterator();
+ while (designates.hasNext()) {
+ Designate designate = (Designate) designates.next();
+
+ // get the OCD reference, ignore the designate if none
+ DesignateObject object = designate.getObject();
+ String ocdRef = (object == null) ? null : object.getOcdRef();
+ if (ocdRef == null) {
+ continue;
+ }
+
+ // get ocd for the reference, ignore designate if none
+ OCD ocd = (OCD) md.getObjectClassDefinitions().get(ocdRef);
+ if (ocd == null) {
+ continue;
+ }
+
+ // gather pids and factory pids
+ this.pids.add(designate.getPid());
+ if (designate.getFactoryPid() != null) {
+ this.factoryPids.add( designate.getFactoryPid() );
+ }
+
+ // register a metatype provider for the pid
+ this.addMetaTypeProvider(designate.getPid(), dmtp);
+ }
+ }
+ }
+
+ protected void addPids(String[] pids) {
+ this.addValues(this.pids, pids);
+ }
+
+ protected void removePid(String pid) {
+ this.pids.remove(pid);
+ }
+
+ protected void addFactoryPids(String[] factoryPids) {
+ this.addValues(this.factoryPids, factoryPids);
+ }
+
+ protected void removeFactoryPid(String factoryPid) {
+ this.factoryPids.remove(factoryPid);
+ }
+
+ protected void addMetaTypeProvider(String key, MetaTypeProvider mtp) {
+ if (key != null && mtp != null) {
+ this.metaTypeProviders.put(key, mtp);
+ this.locales = null;
+ }
+ }
+
+ protected MetaTypeProvider removeMetaTypeProvider(String key) {
+ if (key != null) {
+ this.locales = null;
+ return (MetaTypeProvider) this.metaTypeProviders.remove(key);
+ }
+
+ return null;
+ }
+
+ private void addValues(Collection dest, Object[] values) {
+ if (values != null && values.length > 0) {
+ dest.addAll(Arrays.asList(values));
+ }
+ }
+}