/* * 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.ipojo.manipulator.metadata.annotation.visitor.bind; import org.apache.felix.ipojo.manipulator.metadata.annotation.ComponentWorkbench; import org.apache.felix.ipojo.manipulator.metadata.annotation.visitor.RequiresVisitor; import org.apache.felix.ipojo.metadata.Attribute; import org.apache.felix.ipojo.metadata.Element; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; /** * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> */ public abstract class AbstractBindVisitor extends AnnotationVisitor { protected ComponentWorkbench workbench; protected Action action; public AbstractBindVisitor(ComponentWorkbench workbench, Action action) { super(Opcodes.ASM5); this.workbench = workbench; this.action = action; } /** * Requirement filter. */ protected String m_filter; /** * Is the requirement optional? */ protected String m_optional; /** * Is the requirement aggregate? */ protected String m_aggregate; /** * Required specification. */ protected String m_specification; /** * Requirement id. */ protected String m_id; /** * Binding policy. */ protected String m_policy; /** * Comparator. */ protected String m_comparator; /** * From attribute. */ protected String m_from; /** * proxy attribute. */ protected String m_proxy; /** * Visit annotation's attributes. * * @param name : annotation name * @param value : annotation value * @see org.objectweb.asm.AnnotationVisitor#visit(String, Object) */ public void visit(String name, Object value) { if (name.equals("filter")) { m_filter = value.toString(); return; } if (name.equals("optional")) { m_optional = value.toString(); return; } if (name.equals("aggregate")) { m_aggregate = value.toString(); return; } if (name.equals("specification")) { // Detect whether it's an internal class name. if (value.toString().startsWith("L") && value.toString().endsWith(";")) { Type type = Type.getType(value.toString()); m_specification = type.getClassName(); } else { m_specification = value.toString(); } return; } // Still used by component using the old version of the annotations. if (name.equals("policy")) { m_policy = RequiresVisitor.getPolicy(value.toString()); return; } if (name.equals("id")) { m_id = value.toString(); return; } if (name.equals("comparator")) { Type type = Type.getType(value.toString()); m_comparator = type.getClassName(); return; } if (name.equals("from")) { m_from = value.toString(); } if (name.equals("proxy")) { m_proxy = value.toString(); } } @Override public void visitEnum(String name, String desc, String value) { if (name.equals("policy")) { m_policy = RequiresVisitor.getPolicy(value); } } public void visitEnd() { } protected Element getRequiresElement() { // Check if it is a full-determined requirement Element requires = workbench.getIds().get(m_id); if (requires == null) { // Add the complete requires requires = createRequiresElement(); } else { if (!completeExistingRequires(requires)) return null; } return requires; } protected boolean completeExistingRequires(Element requires) { return completeAttribute(requires, "specification", m_specification) && completeAttribute(requires, "optional", m_optional) && completeAttribute(requires, "aggregate", m_aggregate) && completeAttribute(requires, "filter", m_filter) && completeAttribute(requires, "policy", m_policy) && completeAttribute(requires, "comparator", m_comparator) && completeAttribute(requires, "from", m_from) && completeAttribute(requires, "proxy", m_proxy); } private boolean completeAttribute(Element requires, String name, String value) { // If we have a value if (value != null) { String old = requires.getAttribute(name); if (old == null) { // If the old value was not set, just set the new value requires.addAttribute(new Attribute(name, value)); } else if (!value.equals(old)) { // System.err.println("The '" + name + "' attribute has changed: " + old + " -> " + value); return false; } // Otherwise, the old and new value are equals } return true; } protected Element createRequiresElement() { Element requires; requires = new Element("requires", ""); if (m_specification != null) { requires.addAttribute(new Attribute("specification", m_specification)); } if (m_aggregate != null) { requires.addAttribute(new Attribute("aggregate", m_aggregate)); } if (m_filter != null) { requires.addAttribute(new Attribute("filter", m_filter)); } if (m_optional != null) { requires.addAttribute(new Attribute("optional", m_optional)); } if (m_policy != null) { requires.addAttribute(new Attribute("policy", m_policy)); } if (m_id != null) { requires.addAttribute(new Attribute("id", m_id)); } if (m_comparator != null) { requires.addAttribute(new Attribute("comparator", m_comparator)); } if (m_from != null) { requires.addAttribute(new Attribute("from", m_from)); } if (m_proxy != null) { requires.addAttribute(new Attribute("proxy", m_proxy)); } return requires; } }