MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbOpenJPADomainTypeHandlerImpl.java
1 /*
2  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 
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.
7 
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.
12 
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
16 */
17 
18 package com.mysql.clusterj.openjpa;
19 
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;
27 import java.util.Set;
28 
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;
34 
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;
51 
55 public class NdbOpenJPADomainTypeHandlerImpl<T> implements DomainTypeHandler<T> {
56 
58  static final I18NHelper local = I18NHelper.getInstance(NdbOpenJPADomainTypeHandlerImpl.class);
59 
61  static final Logger logger = LoggerFactoryService.getFactory().getInstance(NdbOpenJPADomainTypeHandlerImpl.class);
62 
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;
74 
76  private NdbOpenJPADomainFieldHandlerImpl[] fieldHandlers;
77 
79  private Set<com.mysql.clusterj.core.store.Column> allStoreColumns =
80  new HashSet<com.mysql.clusterj.core.store.Column>();
81 
83  private List<IndexHandlerImpl> indexHandlerImpls = new ArrayList<IndexHandlerImpl>();
84 
85  private String[] partitionKeyColumnNames;
86 
87  private int numberOfPartitionKeyColumns;
88 
89  private NdbOpenJPADomainFieldHandlerImpl[] partitionKeyFieldHandlers;
90 
91  private NdbOpenJPAConfigurationImpl domainTypeHandlerFactory;
92 
93  private Dictionary dictionary;
94 
95  private Set<NdbOpenJPADomainTypeHandlerImpl<?>> dependencies =
96  new HashSet<NdbOpenJPADomainTypeHandlerImpl<?>>();
97 
98  private Status status = Status.IN_PROCESS;
99 
101  private List<String> reasons = new ArrayList<String>();
102 
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);
118  }
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);
123  }
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);
129  }
130  this.typeName = describedType.getName();
131  org.apache.openjpa.jdbc.schema.Table table = classMapping.getTable();
132  if (table != null) {
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);
140  } else {
141  if (logger.isTraceEnabled()) {
142  logger.trace("initialize for class: " + typeName
143  + " mapped to table: " + storeTable.getName());
144  }
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));
154  }
155  }
156  } else {
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);
161  }
162  // set up the fields
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);
168  }
169  for (FieldMapping fm: allFieldMappings) {
170  if (logger.isDetailEnabled()) logger.detail("field name: " + fm.getName() + " of type: " + fm.getTypeCode());
172  dictionary, this, domainTypeHandlerFactory, fm);
173  fields.add(fmd);
174  if (!fmd.isSupported()) {
175  setUnsupported(fmd.getReason());
176  } else {
177  // add column names to allColumnNames
178  for (com.mysql.clusterj.core.store.Column column: fmd.getStoreColumns()) {
179  allStoreColumns.add(column);
180  }
181  if (fmd.isPrimaryKey()) {
182  primaryKeyFields.add(fmd);
183  }
184  }
185  }
186  primaryKeyFieldNumbers = new int[primaryKeyFields.size()];
187  int i = 0;
188  for (NdbOpenJPADomainFieldHandlerImpl fmd: primaryKeyFields) {
189  primaryKeyFieldNumbers[i++] = fmd.getFieldNumber();
190  }
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) {
195  setUnsupported();
196  reasons.add("Unmapped partition key " + partitionKeyColumnNames[j]);
197  }
198  }
199  }
200 
209  protected void registerPrimaryKeyColumn(NdbOpenJPADomainFieldHandlerImpl fmd,
210  String columnName) {
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;
215  } else {
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);
220  }
221  }
222  return;
223  }
224 
225  public String getName() {
226  return typeName;
227  }
228 
229  public Class<?> getOidClass() {
230  return oidClass;
231  }
232 
233  public String getTableName() {
234  return tableName;
235  }
236 
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;
242  }
243  }
244  throw new ClusterJFatalInternalException(
245  local.message("ERR_Unknown_Field_Name", fieldName, this.getName()));
246  }
247 
248  public Class<T> getProxyClass() {
249  return null;
250  }
251 
252  public T newInstance() {
253  throw new ClusterJFatalInternalException(
254  local.message("ERR_Implementation_Should_Not_Occur"));
255  }
256 
257  public void objectMarkModified(ValueHandler handler, String fieldName) {
258  throw new ClusterJFatalInternalException(
259  local.message("ERR_Implementation_Should_Not_Occur"));
260  }
261 
262  public void objectSetKeys(Object keys, Object instance) {
263  throw new ClusterJFatalInternalException(
264  local.message("ERR_Implementation_Should_Not_Occur"));
265  }
266 
267  public void objectSetValues(ResultData rs, ValueHandler handler) {
268  for (NdbOpenJPADomainFieldHandlerImpl fmd: fields) {
269  fmd.objectSetValue(rs, handler);
270  }
271  }
272 
273  public void objectSetValuesExcept(ResultData rs, ValueHandler handler, String indexName) {
274  throw new ClusterJFatalInternalException(
275  local.message("ERR_Implementation_Should_Not_Occur"));
276  }
277 
278  public void objectSetCacheManager(CacheManager cm, Object instance) {
279  }
280 
281  public void objectResetModified(ValueHandler handler) {
282  }
283 
284  public void operationGetValues(Operation op) {
285  for (NdbOpenJPADomainFieldHandlerImpl fmd: fields) {
286  fmd.operationGetValue(op);
287  }
288  }
289 
293  public void operationGetKeys(Operation op) {
294  for (NdbOpenJPADomainFieldHandlerImpl fmd: primaryKeyFields) {
295  fmd.operationGetValue(op);
296  }
297  }
298 
303  public void operationGetValues(Operation op, BitSet fields) {
304  if (fields == null) {
305  operationGetValues(op);
306  } else {
307  int i = 0;
308  for (NdbOpenJPADomainFieldHandlerImpl fmd: this.fields) {
309  if (fields.get(i++)) {
310  fmd.operationGetValue(op);
311  }
312  }
313  }
314  }
315 
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));
321  }
322  fmd.operationSetValue(handler, op);
323  }
324  }
325 
326  public void operationSetModifiedValues(ValueHandler handler, Operation op) {
327  for (NdbOpenJPADomainFieldHandlerImpl fmd: fields) {
328  fmd.operationSetModifiedValue(handler, op);
329  }
330  }
331 
332  public void operationSetValuesExcept(ValueHandler handler, Operation op, String index) {
333  try {
334  for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
335  if (!fmd.includedInIndex(index)) {
336  fmd.operationSetValue(handler, op);
337  }
338  }
339  } catch (Exception exception) {
340  exception.printStackTrace();
341  throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetValuesExcept caught exception", exception);
342  }
343  }
344 
345  public void operationSetModifiedNonPKValues(ValueHandler handler, Operation op) {
346  try {
347  for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
348  if (!fmd.isPrimaryKey()) {
349  fmd.operationSetModifiedValue(handler, op);
350  }
351  }
352  } catch (Exception exception) {
353  exception.printStackTrace();
354  throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetModifiedValuesExcept caught " + exception);
355  }
356  }
357 
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);
364  return (T) instance;
365  }
366 
367  public ValueHandler createKeyValueHandler(Object keys) {
368 
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) {
383  nullKeyValue = true;
384  }
385  }
386  } else {
387  keyValues[primaryKeyFieldMappings[0].getIndex()] = keys;
388  }
389  KeyValueHandlerImpl keyHandler = new KeyValueHandlerImpl(keyValues);
390  return nullKeyValue?null:keyHandler;
391  }
392 
393  public ValueHandler getValueHandler(Object instance) {
394  if (instance instanceof ValueHandler) {
395  return (ValueHandler)instance;
396  } else {
397  OpenJPAStateManager sm = (OpenJPAStateManager)instance;
398  return new NdbOpenJPAValueHandler(sm);
399  }
400  }
401 
402  public ValueHandler getValueHandler(OpenJPAStateManager sm, NdbOpenJPAStoreManager store) {
403  return new NdbOpenJPAValueHandler(sm, store);
404  }
405 
406  public int[] getKeyFieldNumbers() {
407  return primaryKeyFieldNumbers;
408  }
409 
410  public void newInstance(OpenJPAStateManager sm) {
411  // TODO: accommodate subclasses based on results of select
412  sm.initialize(describedType, PCState.PNONTRANS);
413  }
414 
420  CandidateIndexImpl[] result = new CandidateIndexImpl[indexHandlerImpls.size()];
421  int i = 0;
422  for (IndexHandlerImpl indexHandler: indexHandlerImpls) {
423  result[i++] = indexHandler.toCandidateIndexImpl();
424  }
425  return result;
426  }
427 
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());
443  }
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);
456  loadedAny = true;
457  } else {
458  // if not relation, get a list of all fields to load with one lookup
459  requestedFields.add(fieldHandler);
460  }
461  }
462  }
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) {
467  loadedAny = true;
468  fieldHandler.load(sm, store, fetch, result);
469  }
470  }
471  return loadedAny;
472  }
473 
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);
486  }
487  }
488 
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;
496  }
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()) {
502  result.add(column);
503  }
504  }
505  return result;
506  }
507 
514  for (NdbOpenJPADomainFieldHandlerImpl domainFieldHandler: fieldHandlers) {
515  if (fm.equals(domainFieldHandler.getFieldMapping())) {
516  return domainFieldHandler;
517  }
518  }
520  local.message("ERR_Unknown_Field_Mapping",
521  this.getName(), fm.getName()));
522  }
523 
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;
544  result[0][1] = 0;
545  return result;
546  }
547 
548  public com.mysql.clusterj.core.store.Table getTable() {
549  return storeTable;
550  }
551 
552  public Table getStoreTable() {
553  return storeTable;
554  }
555 
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);
568  }
569  return result;
570  }
571 
575  public NdbOpenJPADomainTypeHandlerImpl<?> registerDependency(ClassMapping mapping) {
576  NdbOpenJPADomainTypeHandlerImpl<?> domainTypeHandler =
577  domainTypeHandlerFactory.getDomainTypeHandler(mapping, dictionary);
578  dependencies.add(domainTypeHandler);
579  return domainTypeHandler;
580  }
581 
585  private enum Status {
586  IN_PROCESS,
587  GOOD,
588  BAD;
589  }
590 
591  private Status supportStatus() {
592  return status;
593  }
594 
595  public void initializeRelations() {
596  for (NdbOpenJPADomainFieldHandlerImpl fieldHandler: fieldHandlers) {
597  fieldHandler.initializeRelations();
598  }
599 
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()) {
610  case IN_PROCESS:
611  workToDo = true;
612  break;
613  case GOOD:
614  break;
615  case BAD:
616  setUnsupported();
617  supported = false;
618  workToDo = true;
619  String message = local.message("ERR_Bad_Dependency", dependent.typeName);
620  reasons.add(message);
621  if (logger.isDebugEnabled()) logger.debug(message);
622  }
623  String message = "Processing class " + typeName + " found dependency " + dependent.typeName
624  + " support status is: " + dependent.supportStatus();
625  if (logger.isDetailEnabled()) logger.detail(message);
626  }
627  if (workToDo) {
628  if (!supported) {
629  // found an unsupported class in the dependency list
630  for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: dependencies) {
631  dependent.setUnsupported();
632  }
633  } else {
634  for (NdbOpenJPADomainTypeHandlerImpl<?> dependent: dependencies) {
635  dependent.setSupported();
636  }
637  }
638  } else {
639  this.setSupported();
640  }
641  if (logger.isDetailEnabled()) logger.detail("Processing class " + typeName + " has dependencies " + dependencies);
642  if (logger.isDetailEnabled()) logger.detail("Processing class " + typeName + " has dependencies " + dependencies);
643  }
644 
645  private Set<NdbOpenJPADomainTypeHandlerImpl<?>> getDependencies() {
646  return dependencies;
647  }
648 
649  private void setUnsupported() {
650  if (status != Status.BAD) {
651  if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as BAD.");
652  status = Status.BAD;
653  }
654  }
655 
656  private void setUnsupported(String reason) {
657  if (status != Status.BAD) {
658  if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as BAD.");
659  status = Status.BAD;
660  }
661  reasons.add(reason);
662  }
663 
664  private void setSupported() {
665  if (status != Status.GOOD) {
666  if (logger.isDetailEnabled()) logger.detail("Class " + typeName + " marked as GOOD.");
667  status = Status.GOOD;
668  }
669  }
670 
671  public boolean isSupportedType() {
672  return Status.GOOD == status;
673  }
674 
675  public String getReasons() {
676  if (reasons.size() == 0) {
677  return null;
678  }
679  StringBuilder result = new StringBuilder(
680  local.message("MSG_Unsupported_Class", getName()));
681  for (String reason:reasons) {
682  result.append('\n');
683  result.append(reason);
684  result.append(';');
685  }
686  result.append('\n');
687  return result.toString();
688  }
689 
690  @Override
691  public String toString() {
692  return "NdbOpenJPADomainTypeHandlerImpl:" + typeName;
693  }
694 
695  public String[] getFieldNames() {
696  throw new ClusterJFatalInternalException(
697  local.message("ERR_Implementation_Should_Not_Occur"));
698  }
699 
700  public void operationSetValues(ValueHandler valueHandler, Operation op) {
701  try {
702  for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
703  fmd.operationSetValue(valueHandler, op);
704  }
705  } catch (Exception exception) {
706  exception.printStackTrace();
707  throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetValues caught exception", exception);
708  }
709  }
710 
711  public void operationSetNonPKValues(ValueHandler valueHandler, Operation op) {
712  try {
713  for (NdbOpenJPADomainFieldHandlerImpl fmd : fields) {
714  if (!fmd.isPrimaryKey()) {
715  fmd.operationSetValue(valueHandler, op);
716  }
717  }
718  } catch (Exception exception) {
719  exception.printStackTrace();
720  throw new RuntimeException("NdbOpenJPADomainTypeHandlerImpl.operationSetNonPKValues caught exception", exception);
721  }
722  }
723 
724 }