001 /*
002 GRANITE DATA SERVICES
003 Copyright (C) 2007-2010 ADEQUATE SYSTEMS SARL
004
005 This file is part of Granite Data Services.
006
007 Granite Data Services is free software; you can redistribute it and/or modify
008 it under the terms of the GNU Library General Public License as published by
009 the Free Software Foundation; either version 2 of the License, or (at your
010 option) any later version.
011
012 Granite Data Services is distributed in the hope that it will be useful, but
013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
015 for more details.
016
017 You should have received a copy of the GNU Library General Public License
018 along with this library; if not, see <http://www.gnu.org/licenses/>.
019
020
021 SLSB: This class and all the modifications to use it are marked with the 'SLSB' tag.
022 */
023
024 package org.granite.generator.as3.reflect;
025
026 import java.lang.annotation.Annotation;
027 import java.lang.reflect.Method;
028 import java.lang.reflect.Modifier;
029 import java.net.URL;
030 import java.util.ArrayList;
031 import java.util.Collections;
032 import java.util.HashSet;
033 import java.util.List;
034 import java.util.Set;
035
036 import org.granite.generator.as3.reflect.JavaMethod.MethodType;
037 import org.granite.messaging.service.annotations.IgnoredMethod;
038 import org.granite.messaging.service.annotations.RemoteDestination;
039
040 /**
041 * @author Franck WOLFF
042 */
043 public class JavaRemoteDestination extends JavaAbstractType {
044
045 // /////////////////////////////////////////////////////////////////////////
046 // Fields.
047
048 protected final Set<JavaImport> imports = new HashSet<JavaImport>();
049 protected final JavaType superclass;
050 protected final List<JavaMethod> methods;
051 protected final String destinationName;
052 protected final String channelId;
053
054 // /////////////////////////////////////////////////////////////////////////
055 // Constructor.
056
057 public JavaRemoteDestination(JavaTypeFactory provider, Class<?> type, URL url) {
058 super(provider, type, url);
059
060 // Find superclass (controller filtered).
061 this.superclass = provider.getJavaTypeSuperclass(type);
062
063 // Collect methods.
064 this.methods = Collections.unmodifiableList(initMethods());
065
066 // Collect imports.
067 if (superclass != null)
068 addToImports(provider.getJavaImport(superclass.getType()));
069
070 RemoteDestination rd = type.getAnnotation(RemoteDestination.class);
071 if (rd != null) {
072 destinationName = rd.id();
073 channelId = rd.channel();
074 }
075 else {
076 destinationName = null;
077 channelId = null;
078 }
079 }
080
081 // /////////////////////////////////////////////////////////////////////////
082 // Properties.
083
084 public Set<JavaImport> getImports() {
085 return imports;
086 }
087
088 protected void addToImports(JavaImport javaImport) {
089 if (javaImport != null)
090 imports.add(javaImport);
091 }
092
093 public boolean hasSuperclass() {
094 return superclass != null;
095 }
096
097 public JavaType getSuperclass() {
098 return superclass;
099 }
100
101 public String getDestinationName() {
102 return destinationName;
103 }
104
105 public String getChannelId() {
106 return channelId;
107 }
108
109 public boolean isAnnotationPresent(Class<? extends Annotation> annotation) {
110 return type.isAnnotationPresent(annotation);
111 }
112
113 // /////////////////////////////////////////////////////////////////////////
114 // Utilities.
115
116 protected List<JavaMethod> initMethods() {
117 List<JavaMethod> methodMap = new ArrayList<JavaMethod>();
118
119 // Get all methods for interfaces: normally, even if it is possible in Java
120 // to override a method into a inherited interface, there is no meaning
121 // to do so (we just ignore potential compilation issues with generated AS3
122 // classes for this case since it is always possible to remove the method
123 // re-declaration in the child interface).
124 Method[] methods = null;
125 if (type.isInterface())
126 methods = type.getMethods();
127 else
128 methods = type.getDeclaredMethods();
129
130 for (Method method : methods) {
131 if (Modifier.isPublic(method.getModifiers()) &&
132 !Modifier.isStatic(method.getModifiers()) &&
133 !method.isAnnotationPresent(IgnoredMethod.class)) {
134 for (Class<?> clazz : method.getParameterTypes()) {
135 if (clazz.isMemberClass() && !clazz.isEnum()) {
136 throw new UnsupportedOperationException(
137 "Inner classes are not supported (except enums): " + clazz
138 );
139 }
140 addToImports(provider.getJavaImport(clazz));
141 }
142
143 methodMap.add(new JavaMethod(method, MethodType.OTHER, this.provider));
144 }
145 }
146
147 return methodMap;
148 }
149
150 public JavaInterface convertToJavaInterface() {
151 return new JavaInterface(getProvider(), getType(), getUrl());
152 }
153 }