PageRenderTime 72ms CodeModel.GetById 59ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/src/com/google/appengine/datanucleus/MetaDataUtils.java

http://datanucleus-appengine.googlecode.com/
Java | 166 lines | 104 code | 17 blank | 45 comment | 27 complexity | baf8cd19db4ae2687678cdc34b2309c5 MD5 | raw file
  1/**********************************************************************
  2Copyright (c) 2011 Google Inc.
  3
  4Licensed under the Apache License, Version 2.0 (the "License");
  5you may not use this file except in compliance with the License.
  6You may obtain a copy of the License at
  7
  8http://www.apache.org/licenses/LICENSE-2.0
  9
 10Unless required by applicable law or agreed to in writing, software
 11distributed under the License is distributed on an "AS IS" BASIS,
 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13See the License for the specific language governing permissions and
 14limitations under the License.
 15**********************************************************************/
 16package com.google.appengine.datanucleus;
 17
 18import org.datanucleus.ClassLoaderResolver;
 19import org.datanucleus.metadata.AbstractClassMetaData;
 20import org.datanucleus.metadata.AbstractMemberMetaData;
 21import org.datanucleus.metadata.ColumnMetaData;
 22import org.datanucleus.metadata.IdentityMetaData;
 23import org.datanucleus.metadata.IdentityType;
 24import org.datanucleus.metadata.InheritanceStrategy;
 25import org.datanucleus.metadata.MetaDataManager;
 26
 27/**
 28 * Series of utilities for interrogating metadata, particularly for GAE/J extensions.
 29 */
 30public class MetaDataUtils {
 31
 32  /**
 33   * Accessor for the default value specified for the provided member.
 34   * If no defaultValue is provided on the column then returns null.
 35   * @param mmd Metadata for the member
 36   * @return The default value
 37   */
 38  public static String getDefaultValueForMember(AbstractMemberMetaData mmd)
 39  {
 40      ColumnMetaData[] colmds = mmd.getColumnMetaData();
 41      if (colmds == null || colmds.length < 1)
 42      {
 43          return null;
 44      }
 45      return colmds[0].getDefaultValue();
 46  }
 47
 48  public static boolean hasEncodedPKField(AbstractClassMetaData acmd) {
 49    if (acmd.getIdentityType() == IdentityType.DATASTORE) {
 50      IdentityMetaData idmd = acmd.getIdentityMetaData();
 51      return idmd.hasExtension(DatastoreManager.ENCODED_PK);
 52    } else {
 53      int pkFieldNumber = acmd.getPKMemberPositions()[0]; // TODO Cater for composite PKs
 54      return isEncodedPKField(acmd, pkFieldNumber);
 55    }
 56  }
 57
 58  public static boolean isEncodedPKField(AbstractClassMetaData acmd, int fieldNumber) {
 59    return isEncodedPKField(acmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber));
 60  }
 61
 62  public static boolean isEncodedPKField(AbstractMemberMetaData ammd) {
 63    return ammd.hasExtension(DatastoreManager.ENCODED_PK);
 64  }
 65
 66  public static boolean isParentPKField(AbstractClassMetaData acmd, int fieldNumber) {
 67    return isParentPKField(acmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber));
 68  }
 69
 70  public static boolean isParentPKField(AbstractMemberMetaData ammd) {
 71    return ammd.hasExtension(DatastoreManager.PARENT_PK);
 72  }
 73
 74  public static boolean isPKNameField(AbstractClassMetaData acmd, int fieldNumber) {
 75    return isPKNameField(acmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber));
 76  }
 77
 78  public static boolean isPKNameField(AbstractMemberMetaData ammd) {
 79    return ammd.hasExtension(DatastoreManager.PK_NAME);
 80  }
 81
 82  public static boolean isPKIdField(AbstractClassMetaData acmd, int fieldNumber) {
 83    return isPKIdField(acmd.getMetaDataForManagedMemberAtAbsolutePosition(fieldNumber));
 84  }
 85
 86  public static boolean isPKIdField(AbstractMemberMetaData ammd) {
 87    return ammd.hasExtension(DatastoreManager.PK_ID);
 88  }
 89
 90  public static boolean isNewOrSuperclassTableInheritanceStrategy(AbstractClassMetaData cmd) {
 91    while (cmd != null) {
 92      AbstractClassMetaData pcmd = cmd.getSuperAbstractClassMetaData();
 93      if (pcmd == null) {
 94        return cmd.getInheritanceMetaData().getStrategy() == InheritanceStrategy.NEW_TABLE;
 95      }
 96      else if (cmd.getInheritanceMetaData().getStrategy() != InheritanceStrategy.SUPERCLASS_TABLE) {
 97        return false;
 98      }
 99      cmd = pcmd;
100    }
101    return false;
102  }
103
104  /**
105   * Convenience accessor for whether this relation is owned (or not).
106   * Currently assumes owned unless otherwise specified.
107   * @param mmd Metadata for the field/property
108   * @param storeMgr StoreManager
109   * @return Whether it is owned
110   */
111  public static boolean isOwnedRelation(AbstractMemberMetaData mmd, DatastoreManager storeMgr) {
112    if (storeMgr.isDefaultToOwnedRelations()) {
113      // Defaulting to owned unless specified otherwise
114      if ("true".equalsIgnoreCase(mmd.getValueForExtension("gae.unowned"))) {
115        return false;
116      }
117      return true;
118    } else {
119      // Defaulting to unowned unless specified otherwise
120      if ("false".equalsIgnoreCase(mmd.getValueForExtension("gae.unowned"))) {
121        return true;
122      }
123      return false;
124    }
125  }
126
127  /**
128   * Convenience method to return whether or not keys of related objects can be
129   * expected to exist on the parent
130   */
131  public static boolean readRelatedKeysFromParent(DatastoreManager storeMgr, AbstractMemberMetaData mmd) {
132    return !MetaDataUtils.isOwnedRelation(mmd, storeMgr) ||
133        storeMgr.storageVersionAtLeast(StorageVersion.READ_OWNED_CHILD_KEYS_FROM_PARENTS);
134  }
135
136  /**
137   * Convenience method to return the metadata for the field/property of this class that stores the 
138   * parent PK (in metadata as "gae.parent-pk").
139   * @param cmd Metadata for the class
140   * @return The parent PK member metadata (or null, if none)
141   */
142  public static AbstractMemberMetaData getParentPkMemberMetaDataForClass(AbstractClassMetaData cmd, 
143      MetaDataManager mmgr, ClassLoaderResolver clr) {
144    AbstractMemberMetaData[] mmds = cmd.getManagedMembers();
145    for (int i=0;i<mmds.length;i++) {
146      if (MetaDataUtils.isParentPKField(mmds[i])) {
147        return mmds[i];
148      }
149      else if (mmds[i].getEmbeddedMetaData() != null) {
150        // TODO Doubtful if this is really correct. The parent key of this class should not be in an embedded class
151        // since the parent of the embedded class is this class. What if we had two instances of this class embedded?
152        AbstractClassMetaData embCmd = mmgr.getMetaDataForClass(mmds[i].getType(), clr);
153        AbstractMemberMetaData embPkParentMmd = getParentPkMemberMetaDataForClass(embCmd, mmgr, clr);
154        if (embPkParentMmd != null) {
155          return embPkParentMmd;
156        }
157      }
158    }
159
160    AbstractClassMetaData superCmd = cmd.getSuperAbstractClassMetaData();
161    if (superCmd != null) {
162      return getParentPkMemberMetaDataForClass(superCmd, mmgr, clr);
163    }
164    return null;
165  }
166}