Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: e90359a13239f56afa6f573902ee7259f4c47301 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
/*
 * Copyright (c) 2008-2013, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Martin Taal - initial API and implementation
 *    Eike Stepper - maintenance
 */
package org.eclipse.emf.cdo.server.internal.hibernate;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDExternal;
import org.eclipse.emf.cdo.common.id.CDOIDString;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.model.CDOPackageRegistry;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.server.IStore;
import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
import org.eclipse.emf.cdo.server.hibernate.IHibernateMappingProvider;
import org.eclipse.emf.cdo.server.hibernate.IHibernateStore;
import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.util.CDOUtil;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.WrappedException;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;

import org.hibernate.Session;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.proxy.HibernateProxy;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

/**
 * Provides several utility and convenience methods. Mostly related to {@link CDOID} and {@link CDORevision}.
 *
 * @author Martin Taal
 */
public class HibernateUtil
{
  private static final String EXT_POINT = "mappingProviderFactories"; //$NON-NLS-1$

  private static HibernateUtil instance = new HibernateUtil();

  private static final String SEPARATOR = "_;_"; //$NON-NLS-1$

  private static final String MAPPING_PROVIDER_FACTORY_TAG = "mappingProviderFactory"; //$NON-NLS-1$

  private static final String TYPE_ATTRIBUTE = "type"; //$NON-NLS-1$

  private static final String CLASS = "class"; //$NON-NLS-1$

  private static IHibernateMappingProvider.Factory mappingProviderFactoryInstance = null;

  public static IHibernateMappingProvider.Factory getMappingProviderFactoryInstance()
  {
    return mappingProviderFactoryInstance;
  }

  public static void setMappingProviderFactoryInstance(
      IHibernateMappingProvider.Factory theMappingProviderFactoryInstance)
  {
    mappingProviderFactoryInstance = theMappingProviderFactoryInstance;
  }

  /**
   * @return the global singleton instance
   */
  public static HibernateUtil getInstance()
  {
    return instance;
  }

  /**
   * Sets the singleton used by the Hibernate store.
   *
   * @param instance
   *          the instance to set
   */
  public static void setInstance(HibernateUtil instance)
  {
    HibernateUtil.instance = instance;
  }

  // Local copy of the datatype factory
  private DatatypeFactory dataTypeFactory;

  public HibernateUtil()
  {
    try
    {
      dataTypeFactory = DatatypeFactory.newInstance();
    }
    catch (DatatypeConfigurationException ex)
    {
      throw new IllegalStateException("Exception ", ex);
    }
  }

  public DatatypeFactory getDataTypeFactory()
  {
    return dataTypeFactory;
  }

  public void setDataTypeFactory(DatatypeFactory dataTypeFactory)
  {
    this.dataTypeFactory = dataTypeFactory;
  }

  /**
   * @return true if the efeature is {@link CDOResource#getContents()} efeature.
   */
  public boolean isCDOResourceContents(EStructuralFeature eFeature)
  {
    if (!eFeature.getEContainingClass().getEPackage().getNsURI().equals(EresourcePackage.eNS_URI))
    {
      return false;
    }
    if (!eFeature.getEContainingClass().getName().equals(EresourcePackage.eINSTANCE.getCDOResource().getName()))
    {
      return false;
    }
    if (!eFeature.getName().equals(EresourcePackage.eINSTANCE.getCDOResource_Contents().getName()))
    {
      return false;
    }
    return true;
  }

  /**
   * Uses the repository package repository to find the EClass of the identified by the CDOClassifierRef.
   *
   * @param classifierRef
   *          {@link CDOClassifierRef} which identifies an EClass
   * @return the EClass instance identified by the EPackage nsuri and classifier name in the CDOClassifierRef
   * @throws IllegalArgumentException
   *           if the EClass can not be found
   * @see IRepository#getPackageRegistry()
   */
  public EClass getEClass(CDOClassifierRef classifierRef)
  {
    final CDOPackageRegistry registry = getPackageRegistry();
    final EPackage ePackage = registry.getEPackage(classifierRef.getPackageURI());
    if (ePackage == null)
    {
      throw new IllegalArgumentException("No EPackage found with nsuri " + classifierRef.getPackageURI()); //$NON-NLS-1$
    }

    final EClass eClass = (EClass)ePackage.getEClassifier(classifierRef.getClassifierName());
    if (eClass == null)
    {
      throw new IllegalArgumentException("No EClass " + classifierRef.getClassifierName() + " in EPackage " //$NON-NLS-1$ //$NON-NLS-2$
          + ePackage.getNsURI());
    }

    return eClass;
  }

  /**
   * @return the package registry as present in the repository
   * @see HibernateStore#getRepository()
   * @see IRepository#getPackageRegistry()
   */
  public CDOPackageRegistry getPackageRegistry()
  {
    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    return accessor.getStore().getRepository().getPackageRegistry();
  }

  /**
   * Creates an instance of {@link IHibernateStore}.
   *
   * @param mappingProvider
   *          the provider which generates a mapping.
   * @param properties
   *          hibernate and teneo properties combined
   * @return the created HibernateStore
   * @see HibernateStore
   * @since 2.0
   */
  public IHibernateStore createStore(IHibernateMappingProvider mappingProvider, Properties properties)
  {
    HibernateStore store = new HibernateStore(mappingProvider, properties);
    mappingProvider.setHibernateStore(store);
    return store;
  }

  /**
   * Can only be used when Eclipse is running. In standalone scenarios create the mapping strategy instance by directly
   * calling the constructor of the mapping strategy class.
   *
   * @see #createFileMappingProvider(String)
   * @since 2.0
   */
  public IHibernateMappingProvider.Factory createMappingProviderFactory(String type)
  {
    IExtensionRegistry registry = Platform.getExtensionRegistry();
    if (registry == null)
    {
      return getMappingProviderFactoryInstance();
    }
    IConfigurationElement[] elements = registry.getConfigurationElementsFor(OM.BUNDLE_ID, EXT_POINT);
    for (final IConfigurationElement element : elements)
    {
      if (MAPPING_PROVIDER_FACTORY_TAG.equals(element.getName()))
      {
        String typeAttr = element.getAttribute(TYPE_ATTRIBUTE);
        if (ObjectUtil.equals(typeAttr, type))
        {
          try
          {
            return (IHibernateMappingProvider.Factory)element.createExecutableExtension(CLASS);
          }
          catch (CoreException ex)
          {
            throw WrappedException.wrap(ex);
          }
        }
      }
    }

    return getMappingProviderFactoryInstance();
  }

  /**
   * Creates a FileMappingProvider using the passed locations.
   *
   * @param location
   *          the locations to load the mappings from
   * @return a {@link FileHibernateMappingProvider}
   * @since 3.0
   */
  public IHibernateMappingProvider createFileMappingProvider(String location)
  {
    return new FileHibernateMappingProvider(location);
  }

  /**
   * Retrieves the Hibernate Session from the current {@link HibernateStoreAccessor}. The current HibernateStoreAccessor
   * is maintained in the {@link HibernateThreadContext}.
   *
   * @return the current hibernate session, if none is there a new one is created and a transaction is started.
   * @since 2.0
   */
  public Session getHibernateSession()
  {
    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    return accessor.getHibernateSession();
  }

  /**
   * Convenience method to convert the properties of the {@link IStore#getRepository()} to a real java Properties
   * object.
   *
   * @param store
   *          the properties of this store are converted to a real Properties object
   * @return a Properties object with the store properties
   */
  public Properties getPropertiesFromStore(IHibernateStore store)
  {
    final Properties props = new Properties();

    final Map<String, String> storeProps = store.getRepository().getProperties();
    for (String key : storeProps.keySet())
    {
      props.setProperty(key, storeProps.get(key));
    }

    return props;
  }

  /**
   * Checks if the object is a HibernateProxy. If so creates the CDOID without resolving the hibernate proxy. If it not
   * a proxy then the id is retrieved from the object itself. It is assumed to be a CDORevision then.
   */
  public CDOID getCDOID(Object o)
  {
    if (o instanceof HibernateProxy)
    {
      final Object idValue = ((HibernateProxy)o).getHibernateLazyInitializer().getIdentifier();
      final String entityName = ((HibernateProxy)o).getHibernateLazyInitializer().getEntityName();
      final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
      EClass eClass = accessor.getStore().getEClass(entityName);
      if (eClass.isInterface() || eClass.isAbstract())
      {
        // load the object to get the real eClass
        // cdo can't handle cdoids with the interface/abstract references
        // need the concrete implementation
        ((HibernateProxy)o).getHibernateLazyInitializer().initialize();
        final CDORevision loadedRevision = (CDORevision)((HibernateProxy)o).getHibernateLazyInitializer()
            .getImplementation((SessionImplementor)accessor.getHibernateSession());
        return loadedRevision.getID();
      }

      return HibernateUtil.getInstance().createCDOID(new CDOClassifierRef(eClass), idValue);
    }

    return ((CDORevision)o).getID();
  }

  /**
   * Reads the entity name while taking account the fact that the object maybe a Hibernate proxy.
   */
  public String getEntityName(Object o)
  {
    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    if (o instanceof HibernateProxy)
    {
      final String entityName = ((HibernateProxy)o).getHibernateLazyInitializer().getEntityName();
      final EClass eClass = accessor.getStore().getEClass(entityName);
      if (eClass.isInterface() || eClass.isAbstract())
      {
        // load the object to get the real eClass
        // cdo can't handle cdoids with the interface/abstract references
        // need the concrete implementation
        ((HibernateProxy)o).getHibernateLazyInitializer().initialize();
        final CDORevision loadedRevision = (CDORevision)((HibernateProxy)o).getHibernateLazyInitializer()
            .getImplementation((SessionImplementor)accessor.getHibernateSession());
        return accessor.getStore().getEntityName(loadedRevision.getEClass());
      }
      return entityName;
    }

    final EClass eClass = ((CDORevision)o).getEClass();
    return accessor.getStore().getEntityName(eClass);
  }

  /**
   * Deprecated method use: {@link HibernateStore#getEntityName(EClass)}.
   */
  @Deprecated
  public String getEntityName(CDORevision revision)
  {
    return getEntityName((Object)revision);
  }

  /**
   * Converts a CDOID to an unique String representations. Null, {@link CDOIDTemp} and null CDOID's are returned as null
   * value. Supports {@link CDOID} and {@link CDOIDExternal}.
   *
   * @param id
   *          the id to convert
   * @return a unique String
   */
  public String convertCDOIDToString(CDOID id)
  {
    if (id == null || id.isNull() || id.isTemporary())
    {
      return null;
    }

    final StringBuilder sb = new StringBuilder();
    CDOIDUtil.write(sb, id);
    return sb.toString();
  }

  /**
   * Converts a String back to its CDOID representation. The same types as in the {@link #convertCDOIDToString(CDOID)}
   * method are supported.
   *
   * @param strID
   *          the String representation of the CDOID
   * @return a valid CDOID, can be null
   */
  public CDOID convertStringToCDOID(String strID)
  {
    if (strID == null)
    {
      return null;
    }

    return CDOIDUtil.read(strID);
  }

  /**
   * Translates a temporary {@link CDOID} into a hibernate ID, by finding the object it refers to in the
   * {@link CommitContext} and then returning or by persisting the object. Note assumes that the hibernate session and
   * CommitContext are set in HibernateThreadContext.
   *
   * @param id
   *          the CDOID to translate to a valid id, if the id is already valid then it is returned.
   * @return the passed id or an instance of CDOID which is valid.
   */
  public CDOID getCDOIDHibernate(CDOID id)
  {
    if (isStoreCreatedID(id))
    {
      return id;
    }

    final CDORevision revision = getCDORevision(id);
    if (isStoreCreatedID(revision.getID()))
    {
      return revision.getID();
    }

    return getCDOIDHibernate(revision);
  }

  /**
   * Retrieves a {@link CDOID} from the passed CDORevision. If the revision has a non-supported CDOID then the revision
   * is saved to the database.
   *
   * @param revision
   *          the revision to get the id from
   * @return a CDOID supported by this store
   */
  public CDOID getCDOIDHibernate(final CDORevision revision)
  {
    final Session session = getHibernateSession();
    if (!isStoreCreatedID(revision.getID()))
    {
      session.saveOrUpdate(revision);
    }

    checkIsSupportedID(revision.getID());

    return revision.getID();
  }

  /**
   * Retrieves the {@link InternalCDORevision} if the target is a {@link CDOObject} then the CDORevision is retrieved
   * using: {@link CDOObject#cdoRevision()}.
   *
   * @param target
   *          the object which can be a CDOObject or an InternalCDORevision
   * @return the found {@link InternalCDORevision}
   */
  public InternalCDORevision getCDORevision(Object target)
  {
    if (target instanceof CDOObject)
    {
      return (InternalCDORevision)CDOUtil.getCDOObject((EObject)target).cdoRevision();
    }
    return (InternalCDORevision)target;
  }

  /**
   * Gets a current object, first checks the new and dirty objects from the {@link CommitContext}. Otherwise reads it
   * from the session.
   *
   * @param id
   *          the {@link CDOID}, the {@link CDOIDTemp} is resolved against the CommitContext.
   * @return the retrieved {@link CDORevision} or null if the id is a null ({@link CDOIDUtil#isNull(CDOID)})
   */
  public InternalCDORevision getCDORevision(CDOID id)
  {
    if (CDOIDUtil.isNull(id))
    {
      return null;
    }

    if (HibernateThreadContext.isCommitContextSet())
    {
      final HibernateCommitContext commitContext = HibernateThreadContext.getCommitContext();
      InternalCDORevision revision;
      // if ((revision = commitContext.getDirtyObject(id)) != null)
      // {
      // return revision;
      // }

      if ((revision = commitContext.getNewObject(id)) != null)
      {
        return revision;
      }

      // maybe the temp was already translated
      final CDOID newID = commitContext.getCommitContext().getIDMappings().get(id);
      if (newID != null)
      {
        return getCDORevision(newID);
      }
    }

    checkIsSupportedID(id);

    final String entityName = getEntityName(id);
    final Serializable idValue = getIdValue(id);
    return (InternalCDORevision)getHibernateSession().get(entityName, idValue);
  }

  /**
   * Retrieves a {@link InternalCDORevision} from the {@link CommitContext} or from the database/hibernate session.
   * Resolves temporary id's: {@link CDOIDTemp}.
   *
   * @param id
   *          the {@link CDOID} identifying the object,
   * @return the retrieved CDORevision or null if the revision is not found
   */
  public InternalCDORevision getCDORevisionNullable(CDOID id)
  {
    if (CDOIDUtil.isNull(id))
    {
      return null;
    }

    if (HibernateThreadContext.isCommitContextSet())
    {
      final HibernateCommitContext commitContext = HibernateThreadContext.getCommitContext();
      InternalCDORevision revision;
      if ((revision = commitContext.getDirtyObject(id)) != null)
      {
        return revision;
      }

      if ((revision = commitContext.getNewObject(id)) != null)
      {
        return revision;
      }

      // maybe the temp was already translated
      if (id instanceof CDOIDTemp)
      {
        final CDOID newID = commitContext.getCommitContext().getIDMappings().get(id);
        if (newID != null)
        {
          return getCDORevision(newID);
        }
      }
    }

    if (!isStoreCreatedID(id))
    {
      return null;
    }

    final String entityName = getEntityName(id);
    final Serializable idValue = getIdValue(id);
    return (InternalCDORevision)getHibernateSession().get(entityName, idValue);
  }

  /**
   * Converts a String to a containing feature id. Note this is not the same as the feature id. The feature is the
   * containing feature of the passed EObject.
   *
   * @param contained
   *          the object which is contained
   * @param value
   *          the value to convert
   * @return the containing feature id.
   * @see #getContainerFeatureId(EClass, EObject, EStructuralFeature)
   */
  public int convertStringToFeatureID(EObject contained, String value)
  {
    final String[] values = value.split(SEPARATOR);
    final String nsuri = values[0];
    final EPackage eContainerPackage = getPackageRegistry().getEPackage(nsuri);
    final String eContainerEClassName = values[1];
    final EClass eContainingClass = (EClass)eContainerPackage.getEClassifier(eContainerEClassName);

    final EPackage eFeaturePackage = getPackageRegistry().getEPackage(values[2]);

    final String eClassifierName = values[3];
    final EClassifier eClassifier = eFeaturePackage.getEClassifier(eClassifierName);
    final EClass eFeatureClass = (EClass)eClassifier;
    final String eFeatureName = values[4];
    final EStructuralFeature eFeature = eFeatureClass.getEStructuralFeature(eFeatureName);
    return getContainerFeatureId(eContainingClass, contained, eFeature);
  }

  /**
   * Computes a valid containing feature id for a passed containing EClass, the contained object and the
   * EStructuralFeature which can be the container or the containment feature.
   *
   * @param containingEClass
   *          the EClass representing the container
   * @param contained
   *          the EObject which is contained
   * @param eFeature
   *          the EStructuralFeature, can be the efeature of the containingEClass or of the contained.
   */
  public int getContainerFeatureId(EClass containingEClass, EObject contained, EStructuralFeature eFeature)
  {
    if (eFeature instanceof EAttribute)
    {
      // featuremap??
      return InternalEObject.EOPPOSITE_FEATURE_BASE - containingEClass.getFeatureID(eFeature);
    }

    final EReference eReference = (EReference)eFeature;
    if (eReference.getEOpposite() != null)
    {
      final EReference containerEReference = eReference.getEOpposite();
      return contained.eClass().getFeatureID(containerEReference);
    }
    return InternalEObject.EOPPOSITE_FEATURE_BASE - containingEClass.getFeatureID(eReference);
  }

  /**
   * Creates the correct subclass of {@link CDOID} for the passed EClass and hibernate id object.
   *
   * @param classifierRef
   *          the EClass to set in the CDOID
   * @param idValue
   *          the real id value
   * @return a supported instance of CDOID.
   * @see CDOIDUtil
   */
  public CDOID createCDOID(CDOClassifierRef classifierRef, Object idValue)
  {
    if (idValue instanceof String)
    {
      return CDOIDUtil.createStringWithClassifier((String)idValue, classifierRef);
    }

    if (idValue instanceof Long)
    {
      return CDOIDUtil.createLongWithClassifier((Long)idValue, classifierRef);
    }

    throw new IllegalArgumentException("The ID value type " + idValue.getClass() //$NON-NLS-1$
    + " is not supported by this store. Method called with " + classifierRef); //$NON-NLS-1$
  }

  /**
   * Checks if the passed id is created/used by this store.
   *
   * @param id
   *          the {@link CDOID} to check
   * @return true if this is a CDOID which is used/created by this store.
   */
  public boolean isStoreCreatedID(CDOID id)
  {
    // TODO: not the nicest check but we know that only these are supported
    // by the hibernatestore
    return id instanceof CDOClassifierRef.Provider || id instanceof CDOIDExternal;
  }

  /**
   * Checks if the passed {@link CDOID} is a type supported by this store.
   *
   * @param id
   *          the CDOID instance to check
   * @throws IllegalArgumentException
   *           if the passed type is not supported.
   */
  public void checkIsSupportedID(CDOID id)
  {
    if (!isStoreCreatedID(id))
    {
      throw new IllegalArgumentException("This CDOID type " + id + " is not supported by this store. " //$NON-NLS-1$ //$NON-NLS-2$
          + id.getClass().getName());
    }
  }

  /**
   * @param id
   *          CDOID to get the internal id from
   * @return the id used by Hibernate, the String or Long value in the CDOID object.
   */
  public Serializable getIdValue(CDOID id)
  {
    if (id instanceof CDOIDString)
    {
      return ((CDOIDString)id).getStringValue();
    }
    return CDOIDUtil.getLong(id);
  }

  /**
   * Retrieves the entity name for the EClass present in the CDOID.
   *
   * @param id
   *          the {@link CDOID} to get the EClass from
   * @return the entity name for the EClass of the CDOID.
   * @see HibernateStore#getEntityName(EClass)
   */
  public String getEntityName(CDOID id)
  {
    final CDOID localId = resolvePossibleTempId(id);
    final CDOClassifierRef classifierRef = CDOIDUtil.getClassifierRef(localId);
    if (classifierRef == null)
    {
      throw new IllegalArgumentException("This CDOID type of " + id + " is not supported by this store."); //$NON-NLS-1$ //$NON-NLS-2$
    }

    final HibernateStoreAccessor accessor = HibernateThreadContext.getCurrentStoreAccessor();
    return accessor.getStore().getEntityName(classifierRef);
  }

  /**
   * If the passed in id is a temp id, resolve it against the {@link HibernateThreadContext#getCommitContext()}
   */
  public CDOID resolvePossibleTempId(CDOID cdoId)
  {
    if (!(cdoId instanceof CDOIDTemp))
    {
      return cdoId;
    }
    if (HibernateThreadContext.isCommitContextSet())
    {
      final HibernateCommitContext commitContext = HibernateThreadContext.getCommitContext();

      final CDOID newID = commitContext.getCommitContext().getIDMappings().get(cdoId);
      if (newID != null)
      {
        return newID;
      }

      InternalCDORevision revision;
      if ((revision = commitContext.getNewObject(cdoId)) != null)
      {
        return revision.getID();
      }
    }
    return cdoId;
  }

  /**
   * Create a {@link XMLGregorianCalendar} from a {@link Date} instance.
   */
  public XMLGregorianCalendar getXMLGregorianCalendarDate(Date date, boolean dateTime)
  {
    final XMLGregorianCalendar gregCalendar = dataTypeFactory.newXMLGregorianCalendar();
    final Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);

    gregCalendar.setYear(calendar.get(Calendar.YEAR));
    gregCalendar.setMonth(calendar.get(Calendar.MONTH) + 1); // correct with 1 on purpose
    gregCalendar.setDay(calendar.get(Calendar.DAY_OF_MONTH));

    if (dateTime)
    {
      gregCalendar.setHour(calendar.get(Calendar.HOUR_OF_DAY));
      gregCalendar.setMinute(calendar.get(Calendar.MINUTE));
      gregCalendar.setSecond(calendar.get(Calendar.SECOND));
      gregCalendar.setMillisecond(calendar.get(Calendar.MILLISECOND));
    }

    return gregCalendar;
  }

}

Back to the top