abstractconfigintrospector.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 813 行 · 第 1/2 页
JAVA
813 行
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Rodrigo Westrupp */package com.caucho.amber.cfg;import com.caucho.amber.field.IdField;import com.caucho.amber.table.ForeignColumn;import com.caucho.amber.type.BeanType;import com.caucho.amber.type.EntityType;import com.caucho.config.ConfigException;import com.caucho.util.L10N;import java.util.ArrayList;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.logging.Logger;import java.lang.annotation.Annotation;import java.lang.reflect.*;import javax.persistence.JoinColumn;import javax.persistence.Version;/** * Abstract introspector for orm.xml and annotations. */abstract public class AbstractConfigIntrospector { private static final Logger log = Logger.getLogger(AbstractConfigIntrospector.class.getName()); private static final L10N L = new L10N(AbstractConfigIntrospector.class); // annotations allowed for a property static HashSet<String> _propertyAnnotations = new HashSet<String>(); // types allowed with a @Basic annotation static HashSet<String> _basicTypes = new HashSet<String>(); // annotations allowed with a @Basic annotation static HashSet<String> _basicAnnotations = new HashSet<String>(); // types allowed with an @Id annotation static HashSet<String> _idTypes = new HashSet<String>(); // annotations allowed with an @Id annotation static HashSet<String> _idAnnotations = new HashSet<String>(); // annotations allowed with a @ManyToOne annotation static HashSet<String> _manyToOneAnnotations = new HashSet<String>(); // annotations allowed with a @OneToMany annotation static HashSet<String> _oneToManyAnnotations = new HashSet<String>(); // types allowed with a @OneToMany annotation static HashSet<String> _oneToManyTypes = new HashSet<String>(); // annotations allowed with a @ManyToMany annotation static HashSet<String> _manyToManyAnnotations = new HashSet<String>(); // types allowed with a @ManyToMany annotation static HashSet<String> _manyToManyTypes = new HashSet<String>(); // annotations allowed with a @OneToOne annotation static HashSet<String> _oneToOneAnnotations = new HashSet<String>(); // annotations allowed with a @ElementCollection annotation static HashSet<String> _elementCollectionAnnotations = new HashSet<String>(); // types allowed with a @ElementCollection annotation static HashSet<String> _elementCollectionTypes = new HashSet<String>(); // annotations allowed with a @Embedded annotation static HashSet<String> _embeddedAnnotations = new HashSet<String>(); // annotations allowed with a @EmbeddedId annotation static HashSet<String> _embeddedIdAnnotations = new HashSet<String>(); // annotations allowed with a @Version annotation static HashSet<String> _versionAnnotations = new HashSet<String>(); // types allowed with an @Version annotation static HashSet<String> _versionTypes = new HashSet<String>(); AnnotationConfig _annotationCfg = new AnnotationConfig(); /** * Validates a callback method */ void validateCallback(String callbackName, Method method, boolean isListener) throws ConfigException { if (Modifier.isFinal(method.getModifiers())) throw error(method, L.l("'{0}' must not be final. @{1} methods may not be final.", getFullName(method), callbackName)); if (Modifier.isStatic(method.getModifiers())) throw error(method, L.l("'{0}' must not be static. @{1} methods may not be static.", getFullName(method), callbackName)); Class params[] = method.getParameterTypes(); if (isListener) { if (params.length != 1) { throw error(method, L.l("'{0}' must have the <METHOD>(Object) signature for entity listeners.", getFullName(method))); } } else if (params.length != 0) { throw error(method, L.l("'{0}' must not have any arguments. @{1} methods have zero arguments for entities or mapped superclasses.", getFullName(method), callbackName)); } } /** * Validates the bean */ public void validateType(Class type, boolean isEntity) throws ConfigException { if (Modifier.isFinal(type.getModifiers())) throw new ConfigException(L.l("'{0}' must not be final. Entity beans may not be final.", type.getName())); // NOTE: Both abstract and concrete classes can be entities. // MappedSuperclass does not need constructor validation. if (isEntity) validateConstructor(type); for (Method method : type.getMethods()) { if (method.getDeclaringClass().getName().equals("java.lang.Object")) { } else if (Modifier.isFinal(method.getModifiers())) throw error(method, L.l("'{0}' must not be final. Entity beans methods may not be final.", getFullName(method))); } } /** * Checks for a valid constructor. */ public void validateConstructor(Class type) throws ConfigException { for (Constructor ctor : type.getConstructors()) { Class []param = ctor.getParameterTypes(); if (param.length == 0 && (Modifier.isPublic(ctor.getModifiers()) || Modifier.isProtected(ctor.getModifiers()))) return; } // jpa/0gb2 throw new ConfigException(L.l("'{0}' needs a public or protected no-arg constructor. Entity beans must have a public or protected no-arg constructor.", type.getName())); } /** * Validates a non-getter method. */ public void validateNonGetter(Method method) throws ConfigException { Annotation ann = isAnnotatedMethod(method); if (ann != null && ! (ann instanceof Version)) { throw error(method, L.l("'{0}' is not a valid annotation for {1}. Only public getters and fields may have property annotations.", ann, getFullName(method))); } } /** * Validates a non-getter method. */ Annotation isAnnotatedMethod(Method method) throws ConfigException { for (Annotation ann : method.getDeclaredAnnotations()) { if (_propertyAnnotations.contains(ann.getClass().getName())) { return ann; } } return null; } static boolean containsFieldOrCompletion(BeanType type, String fieldName) { // jpa/0l03 while (type != null) { if (type.getField(fieldName) != null) return true; if (type.containsCompletionField(fieldName)) return true; if (type instanceof EntityType) type = ((EntityType) type).getParentType(); } return false; } static void validateAnnotations(AccessibleObject field, String fieldName, String fieldType, HashSet<String> validAnnotations) throws ConfigException { for (Annotation ann : field.getDeclaredAnnotations()) { String name = ann.getClass().getName(); if (! name.startsWith("javax.persistence")) continue; if (! validAnnotations.contains(name)) { throw error(field, L.l("{0} may not have a @{1} annotation. {2} does not allow @{3}.", fieldName, name, fieldType, name)); } } } static String getFullName(Method method) { return method.getName(); } static String toFieldName(String name) { // jpa/0g0d return Character.toLowerCase(name.charAt(0)) + name.substring(1); /* if (Character.isLowerCase(name.charAt(0))) return name; else if (name.length() == 1 || ! Character.isUpperCase(name.charAt(1))) return Character.toLowerCase(name.charAt(0)) + name.substring(1); else return name; */ } static ArrayList<ForeignColumn> calculateColumns(com.caucho.amber.table.AmberTable mapTable, EntityType type, JoinColumn []joinColumns) { if (joinColumns == null || joinColumns.length == 0) return calculateColumns(mapTable, type); ArrayList<ForeignColumn> columns = new ArrayList<ForeignColumn>(); for (int i = 0; i < joinColumns.length; i++) { ForeignColumn foreignColumn; JoinColumn joinColumn = joinColumns[i]; foreignColumn = mapTable.createForeignColumn(joinColumn.name(), type.getId().getKey().getColumns().get(0)); columns.add(foreignColumn); } return columns; } static ArrayList<ForeignColumn> calculateColumns(AccessibleObject field, String fieldName, com.caucho.amber.table.AmberTable mapTable, String prefix, EntityType type, JoinColumn []joinColumnsAnn, HashMap<String, JoinColumnConfig> joinColumnsConfig) throws ConfigException { if ((joinColumnsAnn == null || joinColumnsAnn.length == 0) && (joinColumnsConfig == null || joinColumnsConfig.size() == 0)) return calculateColumns(mapTable, prefix, type); ArrayList<ForeignColumn> columns = new ArrayList<ForeignColumn>(); // #1448 not reproduced. if (type.getId() == null) throw error(field, L.l("Entity {0} has no primary key defined.", type.getName())); ArrayList<IdField> idFields = type.getId().getKeys(); int len; if (joinColumnsAnn != null) len = joinColumnsAnn.length; else len = joinColumnsConfig.size(); if (len != idFields.size()) { throw error(field, L.l("@JoinColumns for {0} do not match number of the primary key columns in {1}. The foreign key columns must match the primary key columns.", fieldName, type.getName())); } Iterator it = null; if (joinColumnsConfig != null) it = joinColumnsConfig.values().iterator(); for (int i = 0; i < len; i++) { ForeignColumn foreignColumn; String name; if (joinColumnsAnn != null) { name = joinColumnsAnn[i].name(); } else { JoinColumnConfig joinColumnConfig = (JoinColumnConfig) it.next(); name = joinColumnConfig.getName(); } foreignColumn = mapTable.createForeignColumn(name, idFields.get(i).getColumns().get(0)); columns.add(foreignColumn); } return columns; } static ConfigException error(AccessibleObject field, String msg) { if (field instanceof Field) return error((Field) field, msg); else return error((Method) field, msg); } static ConfigException error(Field field, String msg) { // XXX: the field is for line numbers in the source, theoretically String className = field.getDeclaringClass().getName(); int line = 0; //field.getLine(); if (line > 0) return new ConfigException(className + ":" + line + ": " + msg); else return new ConfigException(className + "." + field.getName() + ": " + msg); } static ConfigException error(Method field, String msg) { // XXX: the field is for line numbers in the source, theoretically String className = field.getDeclaringClass().getName(); int line = 0; //field.getLine(); if (line > 0) return new ConfigException(className + ":" + line + ": " + msg); else return new ConfigException(className + "." + field.getName() + ": " + msg); } static ArrayList<ForeignColumn> calculateColumns(com.caucho.amber.table.AmberTable mapTable,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?