/*
* Copyright (c) 2003-2006, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* - Neither the name of the KNOPFLERFISH project nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @author Erik Wistrand
* @author Philippe Laporte
*/
package org.knopflerfish.util.metatype;
import org.osgi.framework.*;
import org.osgi.service.cm.Configuration;
import org.osgi.service.metatype.*;
import org.osgi.service.metatype.*;
import java.io.*;
import java.util.*;
import java.net.URL;
/**
* Implementation of the ObjectClassDefinition interface.
*
*/
public class OCD implements ObjectClassDefinition {
URL sourceURL;
String id;
String name;
String localized_name;
String desc;
String localized_desc;
List optAttrs;
List reqAttrs;
List localized_optAttrs;
List localized_reqAttrs;
Hashtable icons = new Hashtable();
Hashtable localized_icons = null;
int maxInstances = 1;
/**
* Create a new, empty ObjectClassDefinition.
*
* @param id unique ID of the definition.
* @param name human-readable name of the definition. If set to
* null,
* use id as name.
* @param desc human-readable description of the definition
* @throws IllegalArgumentException if id is or empty
*/
public OCD(String id,
String name,
String desc,
URL sourceURL) {
if(id == null || "".equals(id)) {
throw new IllegalArgumentException("Id must not be null or empty");
}
this.id = id;
this.name = name != null ? name : id;
this.desc = desc;
this.optAttrs = new ArrayList();
this.reqAttrs = new ArrayList();
this.sourceURL = sourceURL;
}
/**
* Creates an OCD with attribute definitions from an existing
* dictionary.
*
* @param id unique ID of the definition.
* @param name human-readable name of the definition. If set to null,
* use id as name.
* @param desc human-readable description of the definition
* @param props set of key value pairs used for attribute definitions.
* all entries in props will be set as REQUIRED
* atttributes.
* @throws IllegalArgumentException if id is or empty
*
*/
public OCD(String id,
String name,
String desc,
Dictionary props) {
this(id, name, desc, (URL)null);
// System.out.println("OCD " + id + ", props=" + props);
for(Enumeration e = props.keys(); e.hasMoreElements();) {
String key = (String)e.nextElement();
if("service.pid".equals(key.toLowerCase())) {
continue;
}
if("service.factorypid".equals(key.toLowerCase())) {
continue;
}
Object val = props.get(key);
int card = 0;
int type = AD.getType(val);
if(val instanceof Vector) {
card = Integer.MIN_VALUE;
} else if(val.getClass().isArray()) {
card = Integer.MAX_VALUE;
}
AD ad = new AD(key, type, card, key,
card == 0
? new String[] { AD.toString(val) }
: null);
// System.out.println(" add " + ad);
add(ad, REQUIRED);
}
}
/**
* Add an attribute definition
*
* @param attr definition to add
* @param filter either OPTIONAL or REQUIRED
* @throws Illegalargumentexception if filter is not OPTIONAL or REQUIRED
*/
public void add(AD attr, int filter) {
switch(filter) {
case OPTIONAL:
optAttrs.add(attr);
break;
case REQUIRED:
reqAttrs.add(attr);
break;
default:
throw new IllegalArgumentException("Unsupported filter=" + filter);
}
}
public AttributeDefinition[] getAttributeDefinitions(int filter) {
AttributeDefinition[] attrs = null;
switch(filter) {
case ALL: {
ArrayList all = new ArrayList();
if(localized_optAttrs == null){
all.addAll(reqAttrs);
all.addAll(optAttrs);
}
else{
all.addAll(localized_reqAttrs);
all.addAll(localized_optAttrs);
}
AttributeDefinition[] ads = new AttributeDefinition[all.size()];
all.toArray(ads);
return ads;
}
case REQUIRED: {
AttributeDefinition[] ads = new AttributeDefinition[reqAttrs.size()];
if(localized_reqAttrs == null){
reqAttrs.toArray(ads);
}
else{
localized_reqAttrs.toArray(ads);
}
return ads;
}
case OPTIONAL: {
AttributeDefinition[] ads = new AttributeDefinition[optAttrs.size()];
if(localized_optAttrs == null){
optAttrs.toArray(ads);
}
else{
localized_optAttrs.toArray(ads);
}
return ads;
}
default:
throw new IllegalArgumentException("Unsupported filter=" + filter);
}
}
/**
* Get description of OCD.
*/
public String getDescription() {
if(localized_desc != null){
return localized_desc;
}
else{
return desc;
}
}
/**
* This code is handles multiple icon sizes but the spec. currently
* only allows on size.
*
* @param size Size of icon requested, if size is 0 return largest icon.
*/
String getIconURL(int size) {
Hashtable itab = (localized_icons != null) ? localized_icons : icons;
if (size == 0) {
for (Enumeration keys = itab.keys(); keys.hasMoreElements(); ) {
int i = ((Integer)keys.nextElement()).intValue();
if (size < i) {
size = i;
}
}
}
return (String) itab.get(new Integer(size));
}
/**
* This code is handles multiple icon sizes but the spec. currently
* only allows on size.
*
* @param size Size of icon requested, if size is 0 return largest icon.
*/
public InputStream getIcon(int size) throws IOException {
String url = getIconURL(size);
if (url != null) {
if (sourceURL != null) {
return new URL(new URL(sourceURL, "/"), url).openStream();
}
else {
return new URL(url).openStream();
}
}
return null;
}
/**
* Get maximum number of instances. Services return 1, factories
* > 1.
*/
public int getMaxInstances() {
return maxInstances;
}
/**
* Set URL to icon
*/
public void setIconURL(String url) {
icons.put(new Integer(Integer.MAX_VALUE), url);
}
public void addIcon(int size, String url){
icons.put(new Integer(size), url);
}
public String getID() {
return id;
}
public String getName() {
if(localized_name != null){
return localized_name;
}
else{
return name;
}
}
void localize(Dictionary dict){
if(dict != null){
localized_name = localizeName(name, dict);
localized_desc = localizeName(desc, dict);
localized_icons = (Hashtable)icons.clone();
for(Iterator it = localized_icons.entrySet().iterator(); it.hasNext(); ) {
Map.Entry e = (Map.Entry)it.next();
e.setValue(localizeName((String)e.getValue(), dict));
}
localized_reqAttrs = new ArrayList();
for(Iterator it = reqAttrs.iterator(); it.hasNext(); ) {
AD attr = (AD)it.next();
localized_reqAttrs.add(attr.localize(dict));
}
localized_optAttrs = new ArrayList();
for(Iterator it = optAttrs.iterator(); it.hasNext(); ) {
AD attr = (AD)it.next();
localized_optAttrs.add(attr.localize(dict));
}
}
}
String localizeName(String name, Dictionary dict){
if(name.startsWith("%")){
String sub;
if((sub = (String) dict.get(name.substring(1))) != null){
return sub;
}
else{
return name;
}
}
return name;
}
/*
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("OCD[id=" + id);
sb.append("\nname=" + name);
sb.append("\ndesc=" + desc);
sb.append("\nregAttrs=");
for(Iterator it = reqAttrs.iterator(); it.hasNext(); ) {
AttributeDefinition attr = (AttributeDefinition)it.next();
sb.append(attr);
if(it.hasNext()) {
sb.append("\n");
}
}
sb.append("\noptAttrs=");
for(Iterator it = optAttrs.iterator(); it.hasNext(); ) {
AttributeDefinition attr = (AttributeDefinition)it.next();
sb.append(attr);
if(it.hasNext()) {
sb.append("\n");
}
}
sb.append("\n/OCD]");
return sb.toString();
}*/
}