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 + -
显示快捷键?