001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. 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
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.j2ee.jpa.model;
043:
044: import java.util.ArrayList;
045: import java.util.Collection;
046: import java.util.LinkedList;
047: import java.util.List;
048: import javax.lang.model.element.AnnotationMirror;
049: import javax.lang.model.element.Element;
050: import javax.lang.model.element.ExecutableElement;
051: import javax.lang.model.element.TypeElement;
052: import javax.lang.model.element.VariableElement;
053: import javax.lang.model.type.DeclaredType;
054: import javax.lang.model.type.TypeMirror;
055: import javax.lang.model.util.ElementFilter;
056: import org.netbeans.api.java.source.CompilationInfo;
057: import org.netbeans.modules.j2ee.jpa.verification.JPAProblemContext;
058: import org.netbeans.modules.j2ee.metadata.model.api.MetadataModel;
059: import org.netbeans.modules.j2ee.persistence.api.EntityClassScope;
060: import org.netbeans.modules.j2ee.persistence.api.metadata.orm.Embeddable;
061: import org.netbeans.modules.j2ee.persistence.api.metadata.orm.Entity;
062: import org.netbeans.modules.j2ee.persistence.api.metadata.orm.EntityMappingsMetadata;
063: import org.netbeans.modules.j2ee.persistence.api.metadata.orm.MappedSuperclass;
064: import org.openide.filesystems.FileObject;
065:
066: /**
067: *
068: * @author Tomasz.Slota@SUN.COM
069: */
070: public class ModelUtils {
071:
072: public static Entity getEntity(EntityMappingsMetadata metadata,
073: TypeElement clazz) {
074: for (Entity entity : metadata.getRoot().getEntity()) {
075: if (clazz.getQualifiedName().contentEquals(
076: entity.getClass2())) {
077: return entity;
078: }
079: }
080: return null;
081: }
082:
083: public static Entity getEntity(EntityMappingsMetadata metadata,
084: String qualifiedClassName) {
085: for (Entity entity : metadata.getRoot().getEntity()) {
086: if (qualifiedClassName.equals(entity.getClass2())) {
087: return entity;
088: }
089: }
090: return null;
091: }
092:
093: public static Embeddable getEmbeddable(
094: EntityMappingsMetadata metadata, TypeElement clazz) {
095: for (Embeddable embeddable : metadata.getRoot().getEmbeddable()) {
096: if (clazz.getQualifiedName().contentEquals(
097: embeddable.getClass2())) {
098: return embeddable;
099: }
100: }
101: return null;
102: }
103:
104: public static MappedSuperclass getMappedSuperclass(
105: EntityMappingsMetadata metadata, TypeElement clazz) {
106: for (MappedSuperclass mappedSuperclass : metadata.getRoot()
107: .getMappedSuperclass()) {
108: if (clazz.getQualifiedName().contentEquals(
109: mappedSuperclass.getClass2())) {
110: return mappedSuperclass;
111: }
112: }
113: return null;
114: }
115:
116: public static TypeElement getTypeElementFromModel(
117: CompilationInfo info, Object modelElement) {
118: String className = null;
119:
120: if (modelElement instanceof Entity) {
121: className = ((Entity) modelElement).getClass2();
122: }
123:
124: if (className != null) {
125: return info.getElements().getTypeElement(className);
126: }
127:
128: return null;
129: }
130:
131: public static void resolveJavaElementFromModel(
132: JPAProblemContext problemCtx, AttributeWrapper attr) {
133: String attrName = attr.getName();
134:
135: attr.setInstanceVariable(getField(problemCtx.getJavaClass(),
136: attrName));
137: attr
138: .setAccesor(getAccesor(problemCtx.getJavaClass(),
139: attrName));
140:
141: if (attr.getInstanceVariable() != null) {
142: attr.setMutator(getMutator(problemCtx.getCompilationInfo(),
143: problemCtx.getJavaClass(), attr
144: .getInstanceVariable()));
145: }
146:
147: if (problemCtx.getAccessType() == AccessType.FIELD) {
148: attr.setJavaElement(attr.getInstanceVariable());
149: }
150:
151: else if (problemCtx.getAccessType() == AccessType.PROPERTY) {
152: attr.setJavaElement(attr.getAccesor());
153: }
154: }
155:
156: // TODO: reimplement this method to take a type argument and assure 100% accuracy
157: public static ExecutableElement getAccesor(TypeElement clazz,
158: String fieldName) {
159: for (ExecutableElement method : getMethod(clazz,
160: getAccesorName(fieldName))) {
161: if (method.getParameters().size() == 0) {
162: return method;
163: }
164: }
165:
166: for (ExecutableElement method : getMethod(clazz,
167: getBooleanAccesorName(fieldName))) {
168: if (method.getParameters().size() == 0) {
169: return method;
170: }
171: }
172:
173: return null;
174: }
175:
176: public static ExecutableElement getMutator(CompilationInfo info,
177: TypeElement clazz, VariableElement field) {
178: ExecutableElement matchingMethods[] = ModelUtils.getMethod(
179: clazz, ModelUtils.getMutatorName(field.getSimpleName()
180: .toString()));
181:
182: for (ExecutableElement potentialMutator : matchingMethods) {
183: if (potentialMutator.getParameters().size() == 1) {
184: TypeMirror argType = potentialMutator.getParameters()
185: .get(0).asType();
186:
187: if (info.getTypes().isSameType(argType, field.asType())) {
188: return potentialMutator;
189: }
190: }
191: }
192:
193: return null;
194: }
195:
196: public static ExecutableElement[] getMethod(TypeElement clazz,
197: String methodName) {
198: List<ExecutableElement> methods = new ArrayList<ExecutableElement>();
199:
200: for (ExecutableElement method : ElementFilter.methodsIn(clazz
201: .getEnclosedElements())) {
202: if (method.getSimpleName().contentEquals(methodName)) {
203: methods.add(method);
204: }
205: }
206:
207: return methods.toArray(new ExecutableElement[methods.size()]);
208: }
209:
210: public static String getAccesorName(String fieldName) {
211: return "get" //NOI18N
212: + Character.toString(fieldName.charAt(0)).toUpperCase()
213: + fieldName.substring(1);
214: }
215:
216: public static String getBooleanAccesorName(String fieldName) {
217: return "is" //NOI18N
218: + Character.toString(fieldName.charAt(0)).toUpperCase()
219: + fieldName.substring(1);
220: }
221:
222: public static String getMutatorName(String fieldName) {
223: return "set" //NOI18N
224: + Character.toString(fieldName.charAt(0)).toUpperCase()
225: + fieldName.substring(1);
226: }
227:
228: public static String getFieldNameFromAccessor(String accessorName) {
229: if (!accessorName.startsWith("get")) { //NOI18N
230: throw new IllegalArgumentException(
231: "accessor name must start with 'get'");
232: }
233:
234: return String.valueOf(accessorName.charAt(3)).toLowerCase()
235: + accessorName.substring(4);
236: }
237:
238: public static VariableElement getField(TypeElement clazz,
239: String fieldName) {
240: for (VariableElement field : ElementFilter.fieldsIn(clazz
241: .getEnclosedElements())) {
242: if (field.getSimpleName().contentEquals(fieldName)) {
243: return field;
244: }
245: }
246:
247: return null;
248: }
249:
250: public static MetadataModel<EntityMappingsMetadata> getModel(
251: FileObject sourceFile) {
252: EntityClassScope scope = EntityClassScope
253: .getEntityClassScope(sourceFile);
254:
255: if (scope != null) {
256: return scope.getEntityMappingsModel(false); // false since I guess you only want the entity classes defined in the project
257: }
258: return null;
259: }
260:
261: public static Collection<String> extractAnnotationNames(Element elem) {
262: Collection<String> annotationsOnElement = new LinkedList<String>();
263:
264: for (AnnotationMirror ann : elem.getAnnotationMirrors()) {
265: TypeMirror annType = ann.getAnnotationType();
266: Element typeElem = ((DeclaredType) annType).asElement();
267: String typeName = ((TypeElement) typeElem)
268: .getQualifiedName().toString();
269: annotationsOnElement.add(typeName);
270: }
271:
272: return annotationsOnElement;
273: }
274:
275: public static String shortAnnotationName(String annClass) {
276: return "@" + annClass.substring(annClass.lastIndexOf(".") + 1); //NOI18N
277: }
278: }
|