List of usage examples for org.hibernate.type ComponentType getPropertyNullability
@Override public boolean[] getPropertyNullability()
From source file:ome.services.graphs.GraphPathBean.java
License:Open Source License
/** * Process the Hibernate domain object model to initialize this class' instance fields. * No other method should write to them. * @param sessionFactory the Hibernate session factory *//*from w ww.j av a 2 s . com*/ private void initialize(SessionFactoryImplementor sessionFactory) { /* note all the direct superclasses */ final Map<String, String> superclasses = new HashMap<String, String>(); final Map<String, ClassMetadata> classesMetadata = sessionFactory.getAllClassMetadata(); for (final String className : classesMetadata.keySet()) { try { final Class<?> actualClass = Class.forName(className); if (IObject.class.isAssignableFrom(actualClass)) { classesBySimpleName.put(actualClass.getSimpleName(), actualClass.asSubclass(IObject.class)); final Set<String> subclassNames = sessionFactory.getEntityPersister(className) .getEntityMetamodel().getSubclassEntityNames(); for (final String subclassName : subclassNames) { if (!subclassName.equals(className)) { final Class<?> actualSubclass = Class.forName(subclassName); if (actualSubclass.getSuperclass() == actualClass) { superclasses.put(subclassName, className); } } } } else { log.warn("mapped class " + className + " is not a " + IObject.class.getName()); } } catch (ClassNotFoundException e) { log.error("could not instantiate class", e); } } /* note the indirect superclasses and subclasses */ for (final Entry<String, String> superclassRelationship : superclasses.entrySet()) { final String startClass = superclassRelationship.getKey(); String superclass = superclassRelationship.getValue(); while (superclass != null) { allSuperclasses.put(startClass, superclass); allSubclasses.put(superclass, startClass); superclass = superclasses.get(superclass); } } /* queue for processing all the properties of all the mapped entities: name, type, nullability */ final Queue<PropertyDetails> propertyQueue = new LinkedList<PropertyDetails>(); final Map<String, Set<String>> allPropertyNames = new HashMap<String, Set<String>>(); for (final Entry<String, ClassMetadata> classMetadata : classesMetadata.entrySet()) { final String className = classMetadata.getKey(); final ClassMetadata metadata = classMetadata.getValue(); /* note name of identifier property */ classIdProperties.put(metadata.getEntityName(), metadata.getIdentifierPropertyName()); /* queue other properties */ final String[] propertyNames = metadata.getPropertyNames(); final Type[] propertyTypes = metadata.getPropertyTypes(); final boolean[] propertyNullabilities = metadata.getPropertyNullability(); for (int i = 0; i < propertyNames.length; i++) { final List<String> propertyPath = Collections.singletonList(propertyNames[i]); propertyQueue.add( new PropertyDetails(className, propertyPath, propertyTypes[i], propertyNullabilities[i])); } final Set<String> propertyNamesSet = new HashSet<String>(propertyNames.length); propertyNamesSet.addAll(Arrays.asList(propertyNames)); allPropertyNames.put(className, propertyNamesSet); } /* process each property to note entity linkages */ while (!propertyQueue.isEmpty()) { final PropertyDetails property = propertyQueue.remove(); if (ignoreProperty(property.path.get(property.path.size() - 1))) { continue; } /* if the property has a component type, queue the parts for processing */ if (property.type instanceof ComponentType) { final ComponentType componentType = (ComponentType) property.type; final String[] componentPropertyNames = componentType.getPropertyNames(); final Type[] componentPropertyTypes = componentType.getSubtypes(); final boolean[] componentPropertyNullabilities = componentType.getPropertyNullability(); for (int i = 0; i < componentPropertyNames.length; i++) { final List<String> componentPropertyPath = new ArrayList<String>(property.path.size() + 1); componentPropertyPath.addAll(property.path); componentPropertyPath.add(componentPropertyNames[i]); propertyQueue.add(new PropertyDetails(property.holder, componentPropertyPath, componentPropertyTypes[i], componentPropertyNullabilities[i])); } } else { /* determine if another mapped entity class is linked by this property */ final boolean isAssociatedEntity; if (property.type instanceof CollectionType) { final CollectionType ct = (CollectionType) property.type; isAssociatedEntity = sessionFactory.getCollectionPersister(ct.getRole()).getElementType() .isEntityType(); } else { isAssociatedEntity = property.type instanceof AssociationType; } /* the property can link to entities, so process it further */ String propertyPath = Joiner.on('.').join(property.path); /* find if the property is accessible (e.g., not protected) */ boolean propertyIsAccessible = false; String classToInstantiateName = property.holder; Class<?> classToInstantiate = null; try { classToInstantiate = Class.forName(classToInstantiateName); while (Modifier.isAbstract(classToInstantiate.getModifiers())) { classToInstantiateName = allSubclasses.get(classToInstantiateName).iterator().next(); classToInstantiate = Class.forName(classToInstantiateName); } try { PropertyUtils.getNestedProperty(classToInstantiate.newInstance(), propertyPath); propertyIsAccessible = true; } catch (NoSuchMethodException e) { /* expected for collection properties */ } catch (NestedNullException e) { log.debug("guessing " + propertyPath + " of " + property.holder + " to be accessible"); propertyIsAccessible = true; } } catch (ReflectiveOperationException e) { log.error("could not probe property " + propertyPath + " of " + property.holder, e); continue; } /* build property report line for log */ final char arrowShaft = property.isNullable ? '-' : '='; final StringBuffer sb = new StringBuffer(); sb.append(property.holder); sb.append(' '); for (final String propertyName : property.path) { sb.append(arrowShaft); sb.append(arrowShaft); sb.append(propertyName); } sb.append(arrowShaft); sb.append(arrowShaft); sb.append("> "); final String valueClassName; if (isAssociatedEntity) { valueClassName = ((AssociationType) property.type).getAssociatedEntityName(sessionFactory); sb.append(valueClassName); } else { valueClassName = null; sb.append("value"); } if (property.type.isCollectionType()) { sb.append("[]"); } if (!propertyIsAccessible) { sb.append(" (inaccessible)"); } /* determine from which class the property is inherited, if at all */ String superclassWithProperty = null; String currentClass = property.holder; while (true) { currentClass = superclasses.get(currentClass); if (currentClass == null) { break; } else if (allPropertyNames.get(currentClass).contains(property.path.get(0))) { superclassWithProperty = currentClass; } } /* check if the property actually comes from an interface */ final String declaringClassName = superclassWithProperty == null ? property.holder : superclassWithProperty; final Class<? extends IObject> interfaceForProperty = getInterfaceForProperty(declaringClassName, property.path.get(0)); /* report where the property is declared */ if (superclassWithProperty != null) { sb.append(" from "); sb.append(superclassWithProperty); } else { if (interfaceForProperty != null) { sb.append(" see "); sb.append(interfaceForProperty.getName()); /* It would be nice to set PropertyDetails to have the interface as the holder, * but then properties would not be unique by declarer class and instance ID. */ } /* entity linkages by non-inherited properties are recorded */ if (valueClassName == null && property.path.size() > 1) { /* assume that the top-level property suffices for describing simple properties */ log.debug("recording " + propertyPath + " as " + property.path.get(0)); propertyPath = property.path.get(0); } final Entry<String, String> classPropertyName = Maps.immutableEntry(property.holder, propertyPath); if (valueClassName == null) { simpleProperties.put(property.holder, propertyPath); } else { linkedTo.put(property.holder, Maps.immutableEntry(valueClassName, propertyPath)); linkedBy.put(valueClassName, classPropertyName); } final PropertyKind propertyKind; if (property.type.isCollectionType()) { propertyKind = PropertyKind.COLLECTION; } else if (property.isNullable) { propertyKind = PropertyKind.OPTIONAL; } else { propertyKind = PropertyKind.REQUIRED; } propertyKinds.put(classPropertyName, propertyKind); if (propertyIsAccessible) { accessibleProperties.add(classPropertyName); } } if (log.isDebugEnabled()) { log.debug(sb.toString()); } } } log.info("initialized graph path bean with " + propertyKinds.size() + " properties"); }
From source file:ome.services.graphs.GraphPathReport.java
License:Open Source License
/** * Process the Hibernate domain object model and write a report of the mapped objects. * @throws IOException if there was a problem in writing to the output file *///ww w. j av a 2s .c o m private static void report() throws IOException { /* note all the direct superclasses and subclasses */ final Map<String, String> superclasses = new HashMap<String, String>(); final SortedSetMultimap<String, String> subclasses = TreeMultimap.create(); @SuppressWarnings("unchecked") final Map<String, ClassMetadata> classesMetadata = sessionFactory.getAllClassMetadata(); for (final String className : classesMetadata.keySet()) { try { final Class<?> actualClass = Class.forName(className); if (IObject.class.isAssignableFrom(actualClass)) { @SuppressWarnings("unchecked") final Set<String> subclassNames = sessionFactory.getEntityPersister(className) .getEntityMetamodel().getSubclassEntityNames(); for (final String subclassName : subclassNames) { if (!subclassName.equals(className)) { final Class<?> actualSubclass = Class.forName(subclassName); if (actualSubclass.getSuperclass() == actualClass) { superclasses.put(subclassName, className); subclasses.put(getSimpleName(className), getSimpleName(subclassName)); } } } } else { System.err.println("error: mapped class " + className + " is not a " + IObject.class.getName()); } } catch (ClassNotFoundException e) { System.err.println("error: could not instantiate class: " + e); } } /* queue for processing all the properties of all the mapped entities: name, type, nullability */ final Queue<PropertyDetails> propertyQueue = new LinkedList<PropertyDetails>(); final Map<String, Set<String>> allPropertyNames = new HashMap<String, Set<String>>(); for (final Map.Entry<String, ClassMetadata> classMetadata : classesMetadata.entrySet()) { final String className = classMetadata.getKey(); final ClassMetadata metadata = classMetadata.getValue(); final String[] propertyNames = metadata.getPropertyNames(); final Type[] propertyTypes = metadata.getPropertyTypes(); final boolean[] propertyNullabilities = metadata.getPropertyNullability(); for (int i = 0; i < propertyNames.length; i++) { if (!ignoreProperty(propertyNames[i])) { final List<String> propertyPath = Collections.singletonList(propertyNames[i]); propertyQueue.add(new PropertyDetails(className, propertyPath, propertyTypes[i], propertyNullabilities[i])); } } final Set<String> propertyNamesSet = new HashSet<String>(propertyNames.length); propertyNamesSet.addAll(Arrays.asList(propertyNames)); allPropertyNames.put(className, propertyNamesSet); } /* for linkedBy, X -> Y, Z: class X is linked to by class Y with Y's property Z */ final SetMultimap<String, Map.Entry<String, String>> linkedBy = HashMultimap.create(); final SetMultimap<String, String> linkers = HashMultimap.create(); final SortedMap<String, SortedMap<String, String>> classPropertyReports = new TreeMap<String, SortedMap<String, String>>(); /* process each property to note entity linkages */ while (!propertyQueue.isEmpty()) { final PropertyDetails property = propertyQueue.remove(); /* if the property has a component type, queue the parts for processing */ if (property.type instanceof ComponentType) { final ComponentType componentType = (ComponentType) property.type; final String[] componentPropertyNames = componentType.getPropertyNames(); final Type[] componentPropertyTypes = componentType.getSubtypes(); final boolean[] componentPropertyNullabilities = componentType.getPropertyNullability(); for (int i = 0; i < componentPropertyNames.length; i++) { if (!ignoreProperty(componentPropertyNames[i])) { final List<String> componentPropertyPath = new ArrayList<String>(property.path.size() + 1); componentPropertyPath.addAll(property.path); componentPropertyPath.add(componentPropertyNames[i]); propertyQueue.add(new PropertyDetails(property.holder, componentPropertyPath, componentPropertyTypes[i], componentPropertyNullabilities[i])); } } } else { /* determine if this property links to another entity */ final boolean isAssociatedEntity; if (property.type instanceof CollectionType) { final CollectionType ct = (CollectionType) property.type; isAssociatedEntity = sessionFactory.getCollectionPersister(ct.getRole()).getElementType() .isEntityType(); } else { isAssociatedEntity = property.type instanceof AssociationType; } /* determine the class and property name for reporting */ final String holderSimpleName = getSimpleName(property.holder); final String propertyPath = Joiner.on('.').join(property.path); /* build a report line for this property */ final StringBuffer sb = new StringBuffer(); final String valueClassName; if (isAssociatedEntity) { /* entity linkages by non-inherited properties are recorded */ final String valueName = ((AssociationType) property.type) .getAssociatedEntityName(sessionFactory); final String valueSimpleName = getSimpleName(valueName); final Map.Entry<String, String> classPropertyName = Maps.immutableEntry(holderSimpleName, propertyPath); linkers.put(holderSimpleName, propertyPath); linkedBy.put(valueSimpleName, classPropertyName); valueClassName = linkTo(valueSimpleName); } else { /* find a Sphinx representation for this property value type */ final UserType userType; if (property.type instanceof CustomType) { userType = ((CustomType) property.type).getUserType(); } else { userType = null; } if (property.type instanceof EnumType) { valueClassName = "enumeration"; } else if (userType instanceof GenericEnumType) { @SuppressWarnings("unchecked") final Class<? extends Unit> unitQuantityClass = ((GenericEnumType) userType) .getQuantityClass(); valueClassName = "enumeration of " + linkToJavadoc(unitQuantityClass.getName()); } else if (property.type instanceof ListType || userType instanceof ListAsSQLArrayUserType) { valueClassName = "list"; } else if (property.type instanceof MapType) { valueClassName = "map"; } else { valueClassName = "``" + property.type.getName() + "``"; } } sb.append(valueClassName); if (property.type.isCollectionType()) { sb.append(" (multiple)"); } else if (property.isNullable) { sb.append(" (optional)"); } /* determine from which class the property is inherited, if at all */ String superclassWithProperty = null; String currentClass = property.holder; while (true) { currentClass = superclasses.get(currentClass); if (currentClass == null) { break; } else if (allPropertyNames.get(currentClass).contains(property.path.get(0))) { superclassWithProperty = currentClass; } } /* check if the property actually comes from an interface */ final String declaringClassName = superclassWithProperty == null ? property.holder : superclassWithProperty; final Class<? extends IObject> interfaceForProperty = getInterfaceForProperty(declaringClassName, property.path.get(0)); /* report where the property is declared */ if (superclassWithProperty != null) { sb.append(" from "); sb.append(linkTo(getSimpleName(superclassWithProperty))); } else { if (interfaceForProperty != null) { sb.append(", see "); sb.append(linkToJavadoc(interfaceForProperty.getName())); } } SortedMap<String, String> byProperty = classPropertyReports.get(holderSimpleName); if (byProperty == null) { byProperty = new TreeMap<String, String>(); classPropertyReports.put(holderSimpleName, byProperty); } byProperty.put(propertyPath, sb.toString()); } } /* the information is gathered, now write the report */ out.write("Glossary of all OMERO Model Objects\n"); out.write("===================================\n\n"); out.write("Overview\n"); out.write("--------\n\n"); out.write("Reference\n"); out.write("---------\n\n"); for (final Map.Entry<String, SortedMap<String, String>> byClass : classPropertyReports.entrySet()) { /* label the class heading */ final String className = byClass.getKey(); out.write(".. _" + labelFor(className) + ":\n\n"); out.write(className + "\n"); final char[] underline = new char[className.length()]; for (int i = 0; i < underline.length; i++) { underline[i] = '"'; } out.write(underline); out.write("\n\n"); /* note the class' relationships */ final SortedSet<String> superclassOf = new TreeSet<String>(); for (final String subclass : subclasses.get(className)) { superclassOf.add(linkTo(subclass)); } final SortedSet<String> linkerText = new TreeSet<String>(); for (final Map.Entry<String, String> linker : linkedBy.get(className)) { linkerText.add(linkTo(linker.getKey(), linker.getValue())); } if (!(superclassOf.isEmpty() && linkerText.isEmpty())) { /* write the class' relationships */ /* out.write("Relationships\n"); out.write("^^^^^^^^^^^^^\n\n"); */ if (!superclassOf.isEmpty()) { out.write("Subclasses: " + Joiner.on(", ").join(superclassOf) + "\n\n"); } if (!linkerText.isEmpty()) { out.write("Used by: " + Joiner.on(", ").join(linkerText) + "\n\n"); } } /* write the class' properties */ /* out.write("Properties\n"); out.write("^^^^^^^^^^\n\n"); */ out.write("Properties:\n"); for (final Map.Entry<String, String> byProperty : byClass.getValue().entrySet()) { final String propertyName = byProperty.getKey(); // if (linkers.containsEntry(className, propertyName)) { // /* label properties that have other entities as values */ // out.write(".. _" + labelFor(className, propertyName) + ":\n\n"); // } out.write(" | " + propertyName + ": " + byProperty.getValue() + "\n" /* \n */); } out.write("\n"); } }