| /* |
| * 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.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| 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 <a href="mailto:dev@felix.apache.org">Felix Project Team</a> |
| */ |
| public class MetaTypeInformationImpl implements MetaTypeInformation |
| { |
| private final Bundle bundle; |
| private final Set pids; |
| private final Set factoryPids; |
| private final Map metaTypeProviders; |
| |
| private Set locales; |
| |
| protected MetaTypeInformationImpl(Bundle bundle) |
| { |
| this.bundle = bundle; |
| this.pids = new HashSet(); |
| this.factoryPids = new HashSet(); |
| this.metaTypeProviders = new HashMap(); |
| } |
| |
| void dispose() |
| { |
| this.pids.clear(); |
| this.factoryPids.clear(); |
| this.locales = null; |
| this.metaTypeProviders.clear(); |
| } |
| |
| /* |
| * (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 HashSet(); |
| 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) |
| { |
| |
| if (id == null || id.length() == 0) |
| { |
| throw new IllegalArgumentException("ObjectClassDefinition ID must not be null or empty"); |
| } |
| |
| MetaTypeProvider mtp = (MetaTypeProvider) this.metaTypeProviders.get(id); |
| if (mtp == null) |
| { |
| throw new IllegalArgumentException("No ObjectClassDefinition for id=" + id); |
| } |
| |
| ObjectClassDefinition ocd = mtp.getObjectClassDefinition(id, locale); |
| if (ocd == null) |
| { |
| throw new IllegalArgumentException("No localized ObjectClassDefinition for id=" + id); |
| } |
| |
| return ocd; |
| } |
| |
| |
| // ---------- 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().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 |
| final Map map = md.getObjectClassDefinitions(); |
| OCD ocd = (OCD) (map == null ? null : map.get(ocdRef)); |
| if (ocd == null) |
| { |
| continue; |
| } |
| |
| // gather pids and factory pids and register provider |
| if (designate.getFactoryPid() != null) |
| { |
| this.factoryPids.add(designate.getFactoryPid()); |
| this.addMetaTypeProvider(designate.getFactoryPid(), dmtp); |
| } |
| else |
| { |
| this.pids.add(designate.getPid()); |
| this.addMetaTypeProvider(designate.getPid(), dmtp); |
| } |
| } |
| } |
| } |
| |
| 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; |
| } |
| |
| protected void addSingletonMetaTypeProvider(String[] pids, MetaTypeProvider mtp) |
| { |
| this.addValues(this.pids, pids); |
| for (int i = 0; i < pids.length; i++) |
| { |
| addMetaTypeProvider(pids[i], mtp); |
| } |
| } |
| |
| protected void addFactoryMetaTypeProvider(String[] factoryPids, MetaTypeProvider mtp) |
| { |
| this.addValues(this.factoryPids, factoryPids); |
| for (int i = 0; i < factoryPids.length; i++) |
| { |
| addMetaTypeProvider(factoryPids[i], mtp); |
| } |
| } |
| |
| protected boolean removeSingletonMetaTypeProvider(String[] pids) |
| { |
| boolean wasRegistered = false; |
| for (int i = 0; i < pids.length; i++) |
| { |
| wasRegistered |= (removeMetaTypeProvider(pids[i]) != null); |
| this.pids.remove(pids[i]); |
| } |
| return wasRegistered; |
| } |
| |
| protected boolean removeFactoryMetaTypeProvider(String[] factoryPids) |
| { |
| boolean wasRegistered = false; |
| for (int i = 0; i < factoryPids.length; i++) |
| { |
| wasRegistered |= (removeMetaTypeProvider(factoryPids[i]) != null); |
| this.factoryPids.remove(factoryPids[i]); |
| } |
| return wasRegistered; |
| } |
| |
| protected void addService(String[] pids, boolean isSingleton, boolean isFactory, final MetaTypeProvider mtp) |
| { |
| } |
| |
| protected void removeService(String[] pids, boolean isSingleton, boolean isFactory) |
| { |
| } |
| |
| private void addValues(Collection dest, Object[] values) |
| { |
| if (values != null && values.length > 0) |
| { |
| dest.addAll(Arrays.asList(values)); |
| } |
| } |
| } |