001 /*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
005 *
006 * The contents of this file are subject to the terms of either the GNU
007 * General Public License Version 2 only ("GPL") or the Common Development
008 * and Distribution License("CDDL") (collectively, the "License"). You
009 * may not use this file except in compliance with the License. You can
010 * obtain a copy of the License at
011 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
012 * or packager/legal/LICENSE.txt. See the License for the specific
013 * language governing permissions and limitations under the License.
014 *
015 * When distributing the software, include this License Header Notice in each
016 * file and include the License file at packager/legal/LICENSE.txt.
017 *
018 * GPL Classpath Exception:
019 * Oracle designates this particular file as subject to the "Classpath"
020 * exception as provided by Oracle in the GPL Version 2 section of the License
021 * file that accompanied this code.
022 *
023 * Modifications:
024 * If applicable, add the following below the License Header, with the fields
025 * enclosed by brackets [] replaced by your own identifying information:
026 * "Portions Copyright [year] [name of copyright owner]"
027 *
028 * Contributor(s):
029 * If you wish your version of this file to be governed by only the CDDL or
030 * only the GPL Version 2, indicate your decision by adding "[Contributor]
031 * elects to include this software in this distribution under the [CDDL or GPL
032 * Version 2] license." If you don't indicate a single choice of license, a
033 * recipient has the option to distribute your version of this file under
034 * either the CDDL, the GPL Version 2 or to extend the choice of license to
035 * its licensees as provided above. However, if you add GPL Version 2 code
036 * and therefore, elected the GPL Version 2 license, then the option applies
037 * only if the new code is made subject to such option by the copyright
038 * holder.
039 */
040
041 package com.sun.enterprise.admin.cli.schemadoc;
042
043 import org.objectweb.asm.AnnotationVisitor;
044 import org.glassfish.api.admin.config.PropertiesDesc;
045 import org.glassfish.api.admin.config.PropertyDesc;
046 import org.jvnet.hk2.config.Attribute;
047
048 public class AttributeMethodVisitor extends EmptyVisitor {
049 private ClassDef def;
050 private String name;
051 private String type;
052 private boolean duckTyped;
053
054 public AttributeMethodVisitor(ClassDef classDef, String method, String aggType) {
055 def = classDef;
056 name = method;
057 type = aggType;
058 def.addAttribute(name, null);
059 }
060
061 @Override
062 public String toString() {
063 return "AttributeMethodVisitor{" +
064 "def=" + def +
065 ", name='" + name + '\'' +
066 ", type='" + type + '\'' +
067 ", duckTyped=" + duckTyped +
068 '}';
069 }
070
071 /**
072 * Visits an annotation of this method.
073 *
074 * @param desc the class descriptor of the annotation class.
075 * @param visible <tt>true</tt> if the annotation is visible at runtime.
076 *
077 * @return a visitor to visit the annotation values, or <tt>null</tt> if this visitor is not interested in visiting
078 * this annotation.
079 */
080 @Override
081 public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
082 duckTyped |= "Lorg/jvnet/hk2/config/DuckTyped;".equals(desc);
083 AnnotationVisitor visitor = null;
084 if ("Lorg/jvnet/hk2/config/Attribute;".equals(desc) || "Lorg/jvnet/hk2/config/Element;".equals(desc)) {
085 try {
086 final Class<?> configurable = Thread.currentThread().getContextClassLoader().loadClass(def.getDef());
087 final Attribute annotation = configurable.getMethod(name).getAnnotation(Attribute.class);
088 def.addAttribute(name, annotation);
089 } catch (Exception e) {
090 throw new RuntimeException(e.getMessage(), e);
091 }
092
093 } else if ("Lorg/glassfish/api/admin/config/PropertiesDesc;".equals(desc)) {
094 try {
095 final Class<?> configurable = Thread.currentThread().getContextClassLoader().loadClass(def.getDef());
096 final PropertiesDesc annotation = configurable.getMethod(name).getAnnotation(PropertiesDesc.class);
097 final PropertyDesc[] propertyDescs = annotation.props();
098 for (PropertyDesc prop : propertyDescs) {
099 def.addProperty(prop);
100 }
101 } catch (Exception e) {
102 throw new RuntimeException(e.getMessage(), e);
103 }
104 }
105 return visitor;
106 }
107
108 @Override
109 public void visitEnd() {
110 if (!duckTyped) {
111 if (!isSimpleType(type)) {
112 def.addAggregatedType(name, type);
113 def.removeAttribute(name);
114 }
115 } else {
116 def.removeAttribute(name);
117 }
118 }
119
120 private boolean isSimpleType(String type) {
121 return type.startsWith("java");
122 }
123 }