| /* |
| * 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.deployment.rp.autoconf; |
| |
| import static org.osgi.service.deploymentadmin.spi.ResourceProcessorException.CODE_OTHER_ERROR; |
| |
| import java.util.Arrays; |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.Vector; |
| |
| import org.apache.felix.metatype.Attribute; |
| import org.apache.felix.metatype.Designate; |
| import org.osgi.service.deploymentadmin.spi.ResourceProcessorException; |
| import org.osgi.service.metatype.AttributeDefinition; |
| import org.osgi.service.metatype.ObjectClassDefinition; |
| |
| /** |
| * Convenience methods to work with MetaType structures. |
| */ |
| public class MetaTypeUtil |
| { |
| private MetaTypeUtil() |
| { |
| // Nop |
| } |
| |
| /** |
| * Determines the actual configuration data based on the specified designate and object class definition |
| * |
| * @param designate The designate object containing the values for the properties |
| * @param ocd The object class definition |
| * @return A dictionary containing data as described in the designate and ocd objects, or <code>null</code> if the designate does not match it's |
| * definition and the designate was marked as optional. |
| * @throws ResourceProcessorException If the designate does not match the ocd and the designate is not marked as optional. |
| */ |
| public static Dictionary getProperties(Designate designate, ObjectClassDefinition ocd) throws ResourceProcessorException |
| { |
| Dictionary properties = new Hashtable(); |
| AttributeDefinition[] attributeDefs = ocd.getAttributeDefinitions(ObjectClassDefinition.ALL); |
| |
| List<Attribute> attributes = designate.getObject().getAttributes(); |
| for (Attribute attribute : attributes) |
| { |
| String adRef = attribute.getAdRef(); |
| boolean found = false; |
| for (int j = 0; j < attributeDefs.length; j++) |
| { |
| AttributeDefinition ad = attributeDefs[j]; |
| if (adRef.equals(ad.getID())) |
| { |
| // found attribute definition |
| Object value = getValue(attribute, ad); |
| if (value == null) |
| { |
| if (designate.isOptional()) |
| { |
| properties = null; |
| break; |
| } |
| else |
| { |
| throw new ResourceProcessorException(CODE_OTHER_ERROR, "Could not match attribute to it's definition: adref=" + adRef); |
| } |
| } |
| properties.put(adRef, value); |
| found = true; |
| break; |
| } |
| } |
| if (!found) |
| { |
| if (designate.isOptional()) |
| { |
| properties = null; |
| break; |
| } |
| else |
| { |
| throw new ResourceProcessorException(CODE_OTHER_ERROR, "Could not find attribute definition: adref=" + adRef); |
| } |
| } |
| } |
| |
| return properties; |
| } |
| |
| /** |
| * Determines the value of an attribute based on an attribute definition |
| * |
| * @param attribute The attribute containing value(s) |
| * @param ad The attribute definition |
| * @return An <code>Object</code> reflecting what was specified in the attribute and it's definition or <code>null</code> if the value did not match it's definition. |
| * @throws ResourceProcessorException in case we're unable to parse the value of an attribute. |
| */ |
| private static Object getValue(Attribute attribute, AttributeDefinition ad) throws ResourceProcessorException |
| { |
| if (attribute == null || ad == null || !attribute.getAdRef().equals(ad.getID())) |
| { |
| // wrong attribute or definition |
| return null; |
| } |
| String[] content = attribute.getContent(); |
| |
| // verify correct type of the value(s) |
| int type = ad.getType(); |
| Object[] typedContent = null; |
| try |
| { |
| for (int i = 0; i < content.length; i++) |
| { |
| String value = content[i]; |
| switch (type) |
| { |
| case AttributeDefinition.BOOLEAN: |
| typedContent = (typedContent == null) ? new Boolean[content.length] : typedContent; |
| typedContent[i] = Boolean.valueOf(value); |
| break; |
| case AttributeDefinition.BYTE: |
| typedContent = (typedContent == null) ? new Byte[content.length] : typedContent; |
| typedContent[i] = Byte.valueOf(value); |
| break; |
| case AttributeDefinition.CHARACTER: |
| typedContent = (typedContent == null) ? new Character[content.length] : typedContent; |
| char[] charArray = value.toCharArray(); |
| if (charArray.length == 1) |
| { |
| typedContent[i] = new Character(charArray[0]); |
| } |
| else |
| { |
| throw new ResourceProcessorException(CODE_OTHER_ERROR, "Unable to parse value for definition: adref=" + ad.getID()); |
| } |
| break; |
| case AttributeDefinition.DOUBLE: |
| typedContent = (typedContent == null) ? new Double[content.length] : typedContent; |
| typedContent[i] = Double.valueOf(value); |
| break; |
| case AttributeDefinition.FLOAT: |
| typedContent = (typedContent == null) ? new Float[content.length] : typedContent; |
| typedContent[i] = Float.valueOf(value); |
| break; |
| case AttributeDefinition.INTEGER: |
| typedContent = (typedContent == null) ? new Integer[content.length] : typedContent; |
| typedContent[i] = Integer.valueOf(value); |
| break; |
| case AttributeDefinition.LONG: |
| typedContent = (typedContent == null) ? new Long[content.length] : typedContent; |
| typedContent[i] = Long.valueOf(value); |
| break; |
| case AttributeDefinition.SHORT: |
| typedContent = (typedContent == null) ? new Short[content.length] : typedContent; |
| typedContent[i] = Short.valueOf(value); |
| break; |
| case AttributeDefinition.STRING: |
| typedContent = (typedContent == null) ? new String[content.length] : typedContent; |
| typedContent[i] = value; |
| break; |
| default: |
| // unsupported type |
| throw new ResourceProcessorException(CODE_OTHER_ERROR, "Unsupported value-type for definition: adref=" + ad.getID()); |
| } |
| } |
| } |
| catch (NumberFormatException nfe) |
| { |
| throw new ResourceProcessorException(CODE_OTHER_ERROR, "Unable to parse value for definition: adref=" + ad.getID()); |
| } |
| |
| // verify cardinality of value(s) |
| int cardinality = ad.getCardinality(); |
| Object result = null; |
| if (cardinality == 0) |
| { |
| if (typedContent.length == 1) |
| { |
| result = typedContent[0]; |
| } |
| else |
| { |
| result = null; |
| } |
| } |
| else if (cardinality == Integer.MIN_VALUE) |
| { |
| result = new Vector(Arrays.asList(typedContent)); |
| } |
| else if (cardinality == Integer.MAX_VALUE) |
| { |
| result = typedContent; |
| } |
| else if (cardinality < 0) |
| { |
| if (typedContent.length <= Math.abs(cardinality)) |
| { |
| result = new Vector(Arrays.asList(typedContent)); |
| } |
| else |
| { |
| result = null; |
| } |
| } |
| else if (cardinality > 0) |
| { |
| if (typedContent.length <= cardinality) |
| { |
| result = typedContent; |
| } |
| else |
| { |
| result = null; |
| } |
| } |
| return result; |
| } |
| } |