2 Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 package com.mysql.clusterj.openjpa;
20 import java.lang.reflect.Modifier;
21 import java.sql.SQLException;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.BitSet;
25 import java.util.HashSet;
26 import java.util.List;
29 import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
30 import org.apache.openjpa.jdbc.meta.ClassMapping;
31 import org.apache.openjpa.jdbc.meta.FieldMapping;
32 import org.apache.openjpa.kernel.OpenJPAStateManager;
33 import org.apache.openjpa.kernel.PCState;
35 import com.mysql.clusterj.ClusterJFatalInternalException;
36 import com.mysql.clusterj.core.CacheManager;
37 import com.mysql.clusterj.core.metadata.IndexHandlerImpl;
38 import com.mysql.clusterj.core.metadata.KeyValueHandlerImpl;
39 import com.mysql.clusterj.core.query.CandidateIndexImpl;
40 import com.mysql.clusterj.core.spi.DomainFieldHandler;
41 import com.mysql.clusterj.core.spi.DomainTypeHandler;
42 import com.mysql.clusterj.core.spi.ValueHandler;
43 import com.mysql.clusterj.core.store.Dictionary;
44 import com.mysql.clusterj.core.store.Operation;
45 import com.mysql.clusterj.core.store.PartitionKey;
46 import com.mysql.clusterj.core.store.ResultData;
47 import com.mysql.clusterj.core.store.Table;
48 import com.mysql.clusterj.core.util.I18NHelper;
49 import com.mysql.clusterj.core.util.Logger;
50 import com.mysql.clusterj.core.util.LoggerFactoryService;
55 public class NdbOpenJPADomainTypeHandlerImpl<T> implements DomainTypeHandler<T> {
57 /** My message translator */
58 static final I18NHelper local = I18NHelper.getInstance(NdbOpenJPADomainTypeHandlerImpl.class);
61 static final Logger logger = LoggerFactoryService.getFactory().getInstance(NdbOpenJPADomainTypeHandlerImpl.class);
63 private String typeName;
64 private Class<T> describedType;
65 private Class<?> oidClass;
66 private Table storeTable;
67 private String tableName;
68 private List<NdbOpenJPADomainFieldHandlerImpl> primaryKeyFields =
69 new ArrayList<NdbOpenJPADomainFieldHandlerImpl>();
70 private int[] primaryKeyFieldNumbers;
71 private List<NdbOpenJPADomainFieldHandlerImpl> fields =
72 new ArrayList<NdbOpenJPADomainFieldHandlerImpl>();
73 private ClassMapping classMapping;
75 /** The field handlers for this persistent type*/
76 private NdbOpenJPADomainFieldHandlerImpl[] fieldHandlers;
78 /** All columns in the mapped table. */
79 private Set<com.mysql.clusterj.core.store.Column> allStoreColumns =
80 new HashSet<com.mysql.clusterj.core.store.Column>();
82 /** The indexes defined for this domain type */
83 private List<IndexHandlerImpl> indexHandlerImpls = new ArrayList<IndexHandlerImpl>();
85 private String[] partitionKeyColumnNames;
87 private int numberOfPartitionKeyColumns;
89 private NdbOpenJPADomainFieldHandlerImpl[] partitionKeyFieldHandlers;
91 private NdbOpenJPAConfigurationImpl domainTypeHandlerFactory;
93 private Dictionary dictionary;
95 private Set<NdbOpenJPADomainTypeHandlerImpl<?>> dependencies =
96 new HashSet<NdbOpenJPADomainTypeHandlerImpl<?>>();
98 private Status status = Status.IN_PROCESS;
100 /** Reasons why this class is not supported by clusterjpa */
101 private List<String> reasons = new ArrayList<String>();
103 @SuppressWarnings("unchecked")
104 NdbOpenJPADomainTypeHandlerImpl(
105 Dictionary dictionary, ClassMapping classMapping,
106 NdbOpenJPAConfigurationImpl domainTypeHandlerFactory) {
107 String message = null;
108 this.dictionary = dictionary;
109 this.domainTypeHandlerFactory = domainTypeHandlerFactory;
110 this.classMapping = classMapping;
111 classMapping.resolve(0xffffffff);
112 oidClass = classMapping.getObjectIdType();
113 this.describedType = (Class<T>)classMapping.getDescribedType();
114 if (classMapping.getPCSuperclass() != null) {
115 // persistent subclasses are not supported
116 message = local.message("ERR_Subclass", this.describedType);
117 setUnsupported(message);
119 if (classMapping.getPCSubclasses() != null && classMapping.getPCSubclasses().length > 0) {
120 // persistent superclasses are not supported
121 message = local.message("ERR_Superclass", this.describedType);
122 setUnsupported(message);
124 int modifiers = describedType.getClass().getModifiers();
125 if (Modifier.isAbstract(modifiers)) {
126 // abstract classes are not supported
127 message = local.message("ERR_Abstract_Class", describedType.getClass().getName());
128 setUnsupported(message);
130 this.typeName = describedType.getName();
131 org.apache.openjpa.jdbc.schema.Table table = classMapping.getTable();
133 this.tableName = table.getFullName();
134 this.storeTable = dictionary.getTable(tableName);
135 if (storeTable == null) {
136 // classes with mapped tables not in cluster are not supported
137 message = local.message("ERR_No_Table", describedType.getClass().getName(), tableName);
138 logger.info(message);
139 setUnsupported(message);
141 if (logger.isTraceEnabled()) {
142 logger.trace("initialize for class: " + typeName
143 + " mapped to table: " + storeTable.getName());
145 // set up the partition keys
146 // the partition key field handlers will be initialized via registerPrimaryKeyColumn
147 partitionKeyColumnNames = storeTable.getPartitionKeyColumnNames();
148 numberOfPartitionKeyColumns = partitionKeyColumnNames.length;
149 partitionKeyFieldHandlers = new NdbOpenJPADomainFieldHandlerImpl[numberOfPartitionKeyColumns];
150 if (logger.isDetailEnabled()) {
151 logger.detail("partition key columns for class: "+ typeName
152 + " partition key columns: " + numberOfPartitionKeyColumns
153 + " names: " + Arrays.toString(partitionKeyColumnNames));
157 // classes without mapped tables are not supported
158 message = local.message("ERR_No_Mapped_Table", describedType.getClass().getName());
159 logger.info(message);
160 setUnsupported(message);
163 List<FieldMapping> allFieldMappings = new ArrayList<FieldMapping>();
164 allFieldMappings.addAll(Arrays.asList(classMapping.getFieldMappings()));
165 FieldMapping versionFieldMapping = classMapping.getVersionFieldMapping();
166 if (versionFieldMapping != null) {
167 allFieldMappings.add(versionFieldMapping);
169 for (FieldMapping fm: allFieldMappings) {
170 if (logger.isDetailEnabled()) logger.detail("field name: " + fm.getName() + " of type: " + fm.getTypeCode());
171 NdbOpenJPADomainFieldHandlerImpl fmd = new NdbOpenJPADomainFieldHandlerImpl(
172 dictionary, this, domainTypeHandlerFactory, fm);
174 if (!fmd.isSupported()) {
175 setUnsupported(fmd.getReason());
177 // add column names to allColumnNames
178 for (com.mysql.clusterj.core.store.Column column: fmd.getStoreColumns()) {
179 allStoreColumns.add(column);
181 if (fmd.isPrimaryKey()) {
182 primaryKeyFields.add(fmd);
186 primaryKeyFieldNumbers = new int[primaryKeyFields.size()];
188 for (NdbOpenJPADomainFieldHandlerImpl fmd: primaryKeyFields) {
189 primaryKeyFieldNumbers[i++] = fmd.getFieldNumber();
191 fieldHandlers = fields.toArray(new NdbOpenJPADomainFieldHandlerImpl[fields.size()]);
192 // check to make sure all partition keys have registered
193 for (int j = 0; j < numberOfPartitionKeyColumns; ++j) {
194 if (partitionKeyFieldHandlers[j] == null) {
196 reasons.add("Unmapped partition key " + partitionKeyColumnNames[j]);
201 /** Register a primary key column field. This is used to associate
202 * primary key and partition key column names with field handlers.
203 * This method is called by the NdbOpenJPADomainFieldHandlerImpl constructor
204 * after the mapped column name is known. It is only called by fields
205 * that are mapped to primary key columns.
206 * @param fmd the field handler instance calling us
207 * @param columnName the name of the column
209 protected void registerPrimaryKeyColumn(NdbOpenJPADomainFieldHandlerImpl fmd,
211 // find the partition key column that matches the primary key column
212 for (int j = 0; j < partitionKeyColumnNames.length; ++j) {
213 if (partitionKeyColumnNames[j].equals(columnName)) {
214 partitionKeyFieldHandlers[j] = fmd;
216 if (logger.isDetailEnabled()) logger.detail(
217 "NdbOpenJPADomainTypeHandlerImpl.registerPrimaryKeyColumn "
218 + "mismatch between partition key column name: " + partitionKeyColumnNames[j]
219 + " and primary key column name: " + columnName);
225 public String getName() {
229 public Class<?> getOidClass() {
233 public String getTableName() {
237 public DomainFieldHandler getFieldHandler(String fieldName) {
238 if (logger.isDetailEnabled()) logger.detail("In " + getName() + " looking for " + fieldName);
239 for (NdbOpenJPADomainFieldHandlerImpl domainFieldHandler: fields) {
240 if (fieldName.equals(domainFieldHandler.getName())) {
241 return domainFieldHandler;
244 throw new ClusterJFatalInternalException(
245 local.message("ERR_Unknown_Field_Name", fieldName, this.getName()));
248 public Class<T> getProxyClass() {
252 public T newInstance() {
253 throw new ClusterJFatalInternalException(
254 local.message("ERR_Implementation_Should_Not_Occur"));
257 public void objectMarkModified(ValueHandler handler, String fieldName) {
258 throw new ClusterJFatalInternalException(
259 local.message("ERR_Implementation_Should_Not_Occur"));
262 public void objectSetKeys(Object keys, Object instance) {
263 throw new ClusterJFatalInternalException(
264 local.message("ERR_Implementation_Should_Not_Occur"));
267 public void objectSetValues(ResultData rs, ValueHandler handler) {
268 for (NdbOpenJPADomainFieldHandlerImpl fmd: fields) {
269 fmd.objectSetValue(rs, handler);
273 public void objectSetValuesExcept(ResultData rs, ValueHandler handler, String indexName) {
274 throw new ClusterJFatalInternalException(
275 local.message("ERR_Implementation_Should_Not_Occur"));
278 public void objectSetCacheManager(CacheManager cm, Object instance) {
281 public void objectResetModified(ValueHandler handler) {
284 public void operationGetValues(Operation op) {
285 for (NdbOpenJPADomainFieldHandlerImpl fmd: fields) {
286 fmd.operationGetValue(op);
290 /** Specify that the key columns are to be returned in the result.
291 * @param op the operation
293 public void operationGetKeys(Operation op) {
294 for (NdbOpenJPADomainFieldHandlerImpl fmd: primaryKeyFields) {
295 fmd.operationGetValue(op);
299 /** Specify the fields to be returned in the result.
300 * @param op the operation
301 * @param fields the fields to be returned by the operation
303 public void operationGetValues(Operation op, BitSet fields) {
304 if (fields == null) {
305 operationGetValues(op);
308 for (NdbOpenJPADomainFieldHandlerImpl fmd: this.fields) {
309 if (fields.get(i++)) {
310 fmd.operationGetValue(op);
316 public void operationSetKeys(ValueHandler handler, Operation op) {
317 for (NdbOpenJPADomainFieldHandlerImpl fmd: primaryKeyFields) {
318 if (logger.isDetailEnabled()) {
319 logger.detail("Class: " + typeName
320 + " Primary Key Field: " + fmd.getName() + handler.pkToString(this));
322 fmd.operationSetValue(handler, op);
326 public void operationSetModifiedValues(ValueHandler handler, Operation op) {
327 for (NdbOpenJPADomainFieldHandlerImpl fmd: fields) {
328 fmd.operationSetModifiedValue(handler, op);
332 public void operationSetValuesExcept(ValueHandler handler, Operation op, String index) {
334 for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
335 if (!fmd.includedInIndex(index)) {
336 fmd.operationSetValue(handler, op);
339 } catch (Exception exception) {
340 exception.printStackTrace();
341 throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetValuesExcept caught exception", exception);
345 public void operationSetModifiedNonPKValues(ValueHandler handler, Operation op) {
347 for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
348 if (!fmd.isPrimaryKey()) {
349 fmd.operationSetModifiedValue(handler, op);
352 } catch (Exception exception) {
353 exception.printStackTrace();
354 throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetModifiedValuesExcept caught " + exception);
358 @SuppressWarnings("unchecked")
359 public T getInstance(ValueHandler handler) {
360 OpenJPAStateManager sm = ((NdbOpenJPAValueHandler)handler).getStateManager();
361 sm.initialize(describedType, PCState.PNONTRANS);
362 Object instance= sm.getManagedInstance();
363 // System.out.println("NdbOpenJPADomainTypeHandlerImpl.getInstance returned " + instance.getClass() + " " + instance);
367 public ValueHandler createKeyValueHandler(Object keys) {
369 FieldMapping[] primaryKeyFieldMappings =
370 classMapping.getPrimaryKeyFieldMappings();
371 int numberOfFields = classMapping.getFieldMappings().length;
372 Object[] keyValues = new Object[numberOfFields];
373 boolean nullKeyValue = false;
374 if (primaryKeyFieldMappings.length != 1) {
375 // for each key field, use the field value accessor to get the
376 // value from the Oid and put it into the proper place in keyValues
377 for (NdbOpenJPADomainFieldHandlerImpl fmd: primaryKeyFields) {
378 // store the key value from the oid into the keyValues array
379 // this can be improved with a smarter KeyValueHandlerImpl
380 Object keyValue = fmd.getKeyValue(keys);
381 keyValues[fmd.getFieldNumber()] = keyValue;
382 if (keyValue == null) {
387 keyValues[primaryKeyFieldMappings[0].getIndex()] = keys;
389 KeyValueHandlerImpl keyHandler = new KeyValueHandlerImpl(keyValues);
390 return nullKeyValue?null:keyHandler;
393 public ValueHandler getValueHandler(Object instance) {
394 if (instance instanceof ValueHandler) {
395 return (ValueHandler)instance;
397 OpenJPAStateManager sm = (OpenJPAStateManager)instance;
398 return new NdbOpenJPAValueHandler(sm);
402 public ValueHandler getValueHandler(OpenJPAStateManager sm, NdbOpenJPAStoreManager store) {
403 return new NdbOpenJPAValueHandler(sm, store);
406 public int[] getKeyFieldNumbers() {
407 return primaryKeyFieldNumbers;
410 public void newInstance(OpenJPAStateManager sm) {
411 // TODO: accommodate subclasses based on results of select
412 sm.initialize(describedType, PCState.PNONTRANS);
415 /** Create a list of candidate indexes to evaluate query terms and
416 * decide what type of scan to use.
417 * @return a new array of CandidateIndexImpl
419 public CandidateIndexImpl[] createCandidateIndexes() {
420 CandidateIndexImpl[] result = new CandidateIndexImpl[indexHandlerImpls.size()];
422 for (IndexHandlerImpl indexHandler: indexHandlerImpls) {
423 result[i++] = indexHandler.toCandidateIndexImpl();
428 /** Load the fields for the persistent instance owned by the sm.
429 * @param sm the StateManager
430 * @param store the StoreManager
431 * @param fields the fields to load
432 * @param fetch the FetchConfiguration
433 * @return true if any field was loaded
435 public boolean load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store,
436 BitSet fields, JDBCFetchConfiguration fetch, Object context) throws SQLException {
437 if (logger.isDetailEnabled()) {
438 StringBuilder buffer = new StringBuilder("load for ");
439 buffer.append(typeName);
440 buffer.append(" for fields ");
441 buffer.append(NdbOpenJPAUtility.printBitSet(sm, fields));
442 logger.detail(buffer.toString());
444 boolean loadedAny = false;
445 List<NdbOpenJPADomainFieldHandlerImpl> requestedFields = new ArrayList<NdbOpenJPADomainFieldHandlerImpl>();
446 for (int i=fields.nextSetBit(0); i>=0; i=fields.nextSetBit(i+1)) {
447 if (!sm.getLoaded().get(i)) {
448 // this field is not loaded
449 NdbOpenJPADomainFieldHandlerImpl fieldHandler = fieldHandlers[i];
450 if (logger.isDebugEnabled()) logger.debug(
451 "loading field " + fieldHandler.getName()
452 + " for column " + fieldHandler.getColumnName());
453 if (fieldHandler.isRelation()) {
454 // if relation, load each field individually with its own query
455 fieldHandler.load(sm, store, fetch);
458 // if not relation, get a list of all fields to load with one lookup
459 requestedFields.add(fieldHandler);
463 if (requestedFields.size() != 0) {
464 // load fields via primary key lookup
465 NdbOpenJPAResult result = store.lookup(sm, this, requestedFields);
466 for (NdbOpenJPADomainFieldHandlerImpl fieldHandler: fieldHandlers) {
468 fieldHandler.load(sm, store, fetch, result);
474 /** Load the fields for the persistent instance owned by the sm.
475 * This is the normal way for fields to be loaded into the instance from a result.
476 * @param sm the StateManager
477 * @param store the StoreManager
478 * @param fetch the FetchConfiguration
480 public void load(OpenJPAStateManager sm, NdbOpenJPAStoreManager store,
481 JDBCFetchConfiguration fetch, NdbOpenJPAResult result) throws SQLException {
482 for (NdbOpenJPADomainFieldHandlerImpl fieldHandler: fieldHandlers) {
483 if (logger.isDebugEnabled()) logger.debug("loading field " + fieldHandler.getName()
484 + " for column " + fieldHandler.getColumnName() + " from result data.");
485 fieldHandler.load(sm, store, fetch, result);
489 /** Get StoreColumns for fields identified by the BitSet
492 public Set<com.mysql.clusterj.core.store.Column> getStoreColumns(BitSet fields) {
493 // iterate the fields and save the columns in a Set
494 if (fields == null) {
495 return allStoreColumns;
497 Set<com.mysql.clusterj.core.store.Column> result =
498 new HashSet<com.mysql.clusterj.core.store.Column>();
499 for (int i=fields.nextSetBit(0); i>=0; i=fields.nextSetBit(i+1)) {
500 NdbOpenJPADomainFieldHandlerImpl fieldHandler = fieldHandlers[i];
501 for (com.mysql.clusterj.core.store.Column column: fieldHandler.getStoreColumns()) {
508 /** Get the DomainFieldHandler for the related field.
510 * @param fm the related field mapping
511 * @return the DomainFieldHandler
513 public NdbOpenJPADomainFieldHandlerImpl getDomainFieldHandler(FieldMapping fm) {
514 for (NdbOpenJPADomainFieldHandlerImpl domainFieldHandler: fieldHandlers) {
515 if (fm.equals(domainFieldHandler.getFieldMapping())) {
516 return domainFieldHandler;
519 throw new ClusterJFatalInternalException(
520 local.message("ERR_Unknown_Field_Mapping",
521 this.getName(), fm.getName()));
524 /** Register an index from a field and return a special int[][] that
525 * contains all indexHandlerImpls in which the
526 * field participates. One index can be defined in the field annotation
527 * and this index is identified here. This method is called by the
528 * FieldHandler constructor after the Index annotation is processed
529 * and the mapped column name is known.
530 * TODO: Currently, only one index is supported per field.
531 * @param fieldHandler the FieldHandler
532 * @param indexName the index name
533 * @param dictionary the dictionary used to validate index metadata
534 * @return the array of array identifying the indexes into the IndexHandler
535 * list and columns in the IndexHandler corresponding to the field
537 public int[][] createIndexHandler( NdbOpenJPADomainFieldHandlerImpl fieldHandler,
538 Dictionary dictionary, String indexName) {
539 IndexHandlerImpl indexHandler = new IndexHandlerImpl(this, dictionary, indexName, fieldHandler);
540 int currentIndex = indexHandlerImpls.size();
541 indexHandlerImpls.add(indexHandler);
542 int[][] result = new int[1][2];
543 result[0][0] = currentIndex;
548 public com.mysql.clusterj.core.store.Table getTable() {
552 public Table getStoreTable() {
556 /** Create a partition key for any operation that knows the primary key.
557 * @param handler the handler that contains the values of the primary key
559 public PartitionKey createPartitionKey(ValueHandler handler) {
560 // create the partition key based on the mapped table
561 PartitionKey result = storeTable.createPartitionKey();
562 // add partition key part value for each partition key field
563 for (NdbOpenJPADomainFieldHandlerImpl fmd: partitionKeyFieldHandlers) {
564 if (logger.isDetailEnabled()) logger.detail(
565 "Field number " + fmd.getFieldNumber()
566 + " column name " + fmd.getColumnName() + " field name " + fmd.getName());
567 fmd.partitionKeySetPart(result, handler);
572 /** Register a dependency on another class. If the class is not already known,
573 * add it to the list of dependencies.
575 public NdbOpenJPADomainTypeHandlerImpl<?> registerDependency(ClassMapping mapping) {
576 NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler =
577 domainTypeHandlerFactory.getDomainTypeHandler(mapping, dictionary);
578 dependencies.add(domainTypeHandler);
579 return domainTypeHandler;
582 /** Status of this class with regard to usability with clusterjpa.
585 private enum Status {
591 private Status supportStatus() {
595 public void initializeRelations() {
596 for (NdbOpenJPADomainFieldHandlerImpl fieldHandler: fieldHandlers) {
597 fieldHandler.initializeRelations();
600 // iterate the dependencies and see if any are not supported
601 boolean supported = status != Status.BAD;
602 boolean workToDo = !supported;
603 // iterate a copy of dependencies to avoid concurrent modification of dependencies
604 List<NdbOpenJPADomainTypeHandlerImpl<?>> copyOfDependencies =
605 new ArrayList<NdbOpenJPADomainTypeHandlerImpl<?>>(dependencies);
606 for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: copyOfDependencies) {
607 // top level class will have recursive list of dependencies including itself
608 this.dependencies.addAll(dependent.getDependencies());
609 switch (dependent.supportStatus()) {
619 String message = local.message("ERR_Bad_Dependency", dependent.typeName);
620 reasons.add(message);
621 if (logger.isDebugEnabled()) logger.debug(message);
623 String message = "Processing class " + typeName + " found dependency " + dependent.typeName
624 + " support status is: " + dependent.supportStatus();
625 if (logger.isDetailEnabled()) logger.detail(message);
629 // found an unsupported class in the dependency list
630 for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: dependencies) {
631 dependent.setUnsupported();
634 for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: dependencies) {
635 dependent.setSupported();
641 if (logger.isDetailEnabled()) logger.detail("Processing class " + typeName + " has dependencies " + dependencies);
642 if (logger.isDetailEnabled()) logger.detail("Processing class " + typeName + " has dependencies " + dependencies);
645 private Set<NdbOpenJPADomainTypeHandlerImpl<?>> getDependencies() {
649 private void setUnsupported() {
650 if (status != Status.BAD) {
651 if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as BAD.");
656 private void setUnsupported(String reason) {
657 if (status != Status.BAD) {
658 if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as BAD.");
664 private void setSupported() {
665 if (status != Status.GOOD) {
666 if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as GOOD.");
667 status = Status.GOOD;
671 public boolean isSupportedType() {
672 return Status.GOOD == status;
675 public String getReasons() {
676 if (reasons.size() == 0) {
679 StringBuilder result = new StringBuilder(
680 local.message("MSG_Unsupported_Class", getName()));
681 for (String reason:reasons) {
683 result.append(reason);
687 return result.toString();
691 public String toString() {
692 return "NdbOpenJPADomainTypeHandlerImpl:" + typeName;
695 public String[] getFieldNames() {
696 throw new ClusterJFatalInternalException(
697 local.message("ERR_Implementation_Should_Not_Occur"));
700 public void operationSetValues(ValueHandler valueHandler, Operation op) {
702 for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
703 fmd.operationSetValue(valueHandler, op);
705 } catch (Exception exception) {
706 exception.printStackTrace();
707 throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetValues caught exception", exception);
711 public void operationSetNonPKValues(ValueHandler valueHandler, Operation op) {
713 for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
714 if (!fmd.isPrimaryKey()) {
715 fmd.operationSetValue(valueHandler, op);
718 } catch (Exception exception) {
719 exception.printStackTrace();
720 throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetNonPKValues caught exception", exception);