blob: a5007f8853bcf40a17498b8fd43f1961d0a8e022 [file] [log] [blame]
/*
* 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.dm.runtime;
import org.apache.felix.dm.BundleDependency;
import org.apache.felix.dm.ConfigurationDependency;
import org.apache.felix.dm.Dependency;
import org.apache.felix.dm.DependencyManager;
import org.apache.felix.dm.ResourceDependency;
import org.apache.felix.dm.ServiceDependency;
import org.osgi.framework.Bundle;
/**
* Class used to build a concrete dependency from meta data.
*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class DependencyBuilder
{
public enum DependencyType
{
ServiceDependency,
TemporalServiceDependency,
ConfigurationDependency,
BundleDependency,
ResourceDependency
}
private MetaData m_metaData;
public DependencyBuilder(MetaData dependencyMetaData)
{
m_metaData = dependencyMetaData;
}
public Dependency build(Bundle b, DependencyManager dm)
throws Exception
{
Dependency dp = null;
DependencyType type;
try
{
type = DependencyType.valueOf(m_metaData.getString(Params.type));
}
catch (IllegalArgumentException e)
{
throw new IllegalArgumentException("no \"type\" parameter found from metaData: " + m_metaData);
}
switch (type)
{
case ServiceDependency:
dp = createServiceDependency(b, dm);
break;
case ConfigurationDependency:
dp = createConfigurationDependency(b, dm);
break;
case BundleDependency:
dp = createBundleDependency(dm);
break;
case ResourceDependency:
dp = createResourceDependency(dm);
break;
default:
throw new IllegalArgumentException("Can't build service dependency: " + type);
}
return dp;
}
private Dependency createServiceDependency(Bundle b, DependencyManager dm)
throws ClassNotFoundException
{
String service = m_metaData.getString(Params.service, null);
Class<?> serviceClass = service != null ? b.loadClass(service) : null;
String serviceFilter = m_metaData.getString(Params.filter, null);
String defaultServiceImpl = m_metaData.getString(Params.defaultImpl, null);
Class<?> defaultServiceImplClass =
(defaultServiceImpl != null) ? b.loadClass(defaultServiceImpl) : null;
String added = m_metaData.getString(Params.added, null);
long timeout = m_metaData.getLong(Params.timeout, -1L);
String changed = timeout != -1 ? null : m_metaData.getString(Params.changed, null);
String removed = timeout != -1 ? null : m_metaData.getString(Params.removed, null);
String swap = m_metaData.getString(Params.swap, null);
String autoConfigField = m_metaData.getString(Params.autoConfig, null);
boolean required = "true".equals(m_metaData.getString(Params.required, "true"));
boolean propagate = "true".equals(m_metaData.getString(Params.propagate, "false"));
boolean dereference = "true".equals(m_metaData.getString(Params.dereference, "true"));
Dependency dp = createServiceDependency(dm, serviceClass,
serviceFilter, defaultServiceImplClass, added, changed,
removed, swap, autoConfigField, timeout, required, propagate, dereference);
return dp;
}
private Dependency createServiceDependency(DependencyManager dm, Class<?> serviceClass,
String serviceFilter, Class<?> defaultServiceImplClass, String added,
String changed, String removed, String swap, String autoConfigField, long timeout, boolean required,
boolean propagate, boolean dereference)
{
ServiceDependency sd = timeout != -1 ? dm.createTemporalServiceDependency(timeout)
: dm.createServiceDependency();
sd.setService(serviceClass, serviceFilter);
if (defaultServiceImplClass != null)
{
sd.setDefaultImplementation(defaultServiceImplClass);
}
sd.setCallbacks(added, changed, removed, swap);
if (autoConfigField != null)
{
sd.setAutoConfig(autoConfigField);
}
if (timeout == -1)
{
sd.setRequired(required);
}
sd.setPropagate(propagate);
sd.setDereference(dereference);
return sd;
}
private Dependency createConfigurationDependency(Bundle b, DependencyManager dm) throws Exception
{
String configType = m_metaData.getString(Params.configType, null);
String[] configTypes = m_metaData.getStrings(Params.configTypes, null);
configTypes = configTypes == null ? ((configType != null) ? new String[] { configType } : null) : configTypes;
String pid = m_metaData.getString(Params.pid);
boolean propagate = "true".equals(m_metaData.getString(Params.propagate, "false"));
String callback = m_metaData.getString(Params.updated, "updated");
boolean required = "true".equals(m_metaData.getString(Params.required, "true"));
return createConfigurationDependency(dm, b, pid, callback, configTypes, propagate, required);
}
private Dependency createConfigurationDependency(DependencyManager dm, Bundle b, String pid, String callback, String[] configTypes, boolean propagate, boolean required)
throws ClassNotFoundException
{
if (pid == null)
{
throw new IllegalArgumentException(
"pid attribute not provided in ConfigurationDependency declaration");
}
ConfigurationDependency cd = dm.createConfigurationDependency();
cd.setPid(pid);
cd.setCallback(callback);
cd.setPropagate(propagate, true /* configuration will override default service properties */);
cd.setRequired(required);
if (configTypes != null)
{
Class<?>[] configTypeClasses = new Class<?>[configTypes.length];
for (int i = 0; i < configTypes.length; i ++)
{
configTypeClasses[i] = b.loadClass(configTypes[i]);
}
cd.setConfigType(configTypeClasses);
}
return cd;
}
/**
* Creates a BundleDependency that we parsed from a component descriptor entry.
* @param b
* @param dm
* @param parser
* @return
*/
private Dependency createBundleDependency(DependencyManager dm)
{
String added = m_metaData.getString(Params.added, null);
String changed = m_metaData.getString(Params.changed, null);
String removed = m_metaData.getString(Params.removed, null);
boolean required = "true".equals(m_metaData.getString(Params.required, "true"));
String filter = m_metaData.getString(Params.filter, null);
int stateMask = m_metaData.getInt(Params.stateMask, -1);
boolean propagate = "true".equals(m_metaData.getString(Params.propagate, "false"));
Dependency dp = createBundleDependency(dm, added, changed, removed, required, propagate, filter,
stateMask);
return dp;
}
private Dependency createBundleDependency(DependencyManager dm, String added, String changed,
String removed, boolean required, boolean propagate, String filter, int stateMask)
{
BundleDependency bd = dm.createBundleDependency();
bd.setCallbacks(added, changed, removed);
bd.setRequired(required);
bd.setPropagate(propagate);
if (filter != null)
{
bd.setFilter(filter);
}
if (stateMask != -1)
{
bd.setStateMask(stateMask);
}
return bd;
}
private Dependency createResourceDependency(DependencyManager dm)
{
String added = m_metaData.getString(Params.added, null);
String changed = m_metaData.getString(Params.changed, null);
String removed = m_metaData.getString(Params.removed, null);
String filter = m_metaData.getString(Params.filter, null);
boolean required = "true".equals(m_metaData.getString(Params.required, "true"));
boolean propagate = "true".equals(m_metaData.getString(Params.propagate, "false"));
String autoConfigField = m_metaData.getString(Params.autoConfig, null);
Dependency dp = createResourceDependency(dm, added, changed, removed, required, filter,
propagate, autoConfigField);
return dp;
}
private Dependency createResourceDependency(DependencyManager dm, String added,
String changed, String removed, boolean required, String filter, boolean propagate,
String autoConfigField)
{
ResourceDependency rd = dm.createResourceDependency();
rd.setCallbacks(added, changed, removed);
rd.setRequired(required);
if (filter != null)
{
rd.setFilter(filter);
}
if (autoConfigField != null)
{
rd.setAutoConfig(autoConfigField);
}
rd.setPropagate(propagate);
return rd;
}
}