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