private static void initializeAndModify( TypesCache temporaryTypes, ObjectType type, List<Class<?>> modifications) { State typeState = type.getState(); Map<String, Object> typeOriginals = typeState.getSimpleValues(); try { type.initialize(); temporaryTypes.add(type); // Apply type-specific modifications. if (modifications != null) { for (Class<?> modification : modifications) { type.modify(modification); } } } catch (IncompatibleClassChangeError ex) { LOGGER.info( "Skipped initializing [{}] because its class is in an inconsistent state! ([{}])", type.getInternalName(), ex.getMessage()); } if (typeState.isNew()) { type.save(); } else if (!typeState.getSimpleValues().equals(typeOriginals)) { temporaryTypes.changed.add(type.getId()); } }
@Override protected void run() { // Fetch the globals, which includes a reference to the root // type. References to other objects can't be resolved, // because the type definitions haven't been loaded yet. refreshGlobals(); ObjectType rootType = getRootType(); if (rootType != null) { // This isn't cleared later, because that's done within // {@link refreshTypes} anyway. TypesCache temporaryTypes = temporaryTypesLocal.get(); if (temporaryTypes == null) { temporaryTypes = new TypesCache(); temporaryTypesLocal.set(temporaryTypes); } temporaryTypes.add(rootType); LOGGER.info("Root type ID for [{}] is [{}]", getDatabase().getName(), rootType.getId()); } // Load all other types based on the root type. Then globals // again in case they reference other typed objects. Then // types again using the information from the fully resolved // globals. refreshTypes(); refreshGlobals(); refreshTypes(); refresher.scheduleWithFixedDelay(5.0, 5.0); }
/** Adds the given {@code type} to all type cache maps. */ public void add(ObjectType type) { String className = type.getObjectClassName(); if (!ObjectUtils.isBlank(className)) { byClassName.put(className.toLowerCase(Locale.ENGLISH), type); } byId.put(type.getId(), type); String internalName = type.getInternalName(); if (!ObjectUtils.isBlank(internalName)) { byName.put(internalName.toLowerCase(Locale.ENGLISH), type); } for (String group : type.getGroups()) { if (group != null) { group = group.toLowerCase(Locale.ENGLISH); } Set<ObjectType> groupTypes = byGroup.get(group); if (groupTypes == null) { groupTypes = new HashSet<ObjectType>(); byGroup.put(group, groupTypes); } groupTypes.remove(type); groupTypes.add(type); } }
@Override protected Map<UUID, Map<UUID, StateValueAdapter<Object, Object>>> create() { bootstrapOnce.ensure(); Map<UUID, Map<UUID, StateValueAdapter<Object, Object>>> adaptersBySourceTypeId = new ConcurrentHashMap<>(); for (Class<?> c : ClassFinder.findConcreteClasses(StateValueAdapter.class)) { TypeDefinition<?> d = TypeDefinition.getInstance(c); Class<?> source = d.getInferredGenericTypeArgumentClass(StateValueAdapter.class, 0); if (source != null) { Class<?> target = d.getInferredGenericTypeArgumentClass(StateValueAdapter.class, 1); if (target != null) { ObjectType sourceType = getTypeByClass(source); if (sourceType != null) { ObjectType targetType = getTypeByClass(target); if (targetType != null) { UUID sourceTypeId = sourceType.getId(); UUID targetTypeId = targetType.getId(); Map<UUID, StateValueAdapter<Object, Object>> adapters = adaptersBySourceTypeId.get(sourceTypeId); if (adapters == null) { adapters = new ConcurrentHashMap<>(); adaptersBySourceTypeId.put(sourceTypeId, adapters); } adapters.put( targetTypeId, (StateValueAdapter<Object, Object>) TypeDefinition.getInstance(c).newInstance()); } } } } } return adaptersBySourceTypeId; }
/** * Initializes the given {@code objectClasses} so that they are usable as {@linkplain ObjectType * types}. */ public void initializeTypes(Iterable<Class<?>> objectClasses) { bootstrapOnce.ensure(); Set<String> classNames = new HashSet<String>(); for (Class<?> objectClass : objectClasses) { classNames.add(objectClass.getName()); } for (ObjectType type : getTypes()) { UUID id = type.getId(); if (classNames.contains(type.getObjectClassName())) { TypesCache temporaryTypes = temporaryTypesLocal.get(); if ((temporaryTypes != null && temporaryTypesLocal.get().changed.contains(id)) || permanentTypes.changed.contains(id)) { type.save(); } } } }
protected Document getTestDocument() { ObjectType documentObjectType = mock(ObjectType.class); when(documentObjectType.getId()).thenReturn(BaseTypeId.CMIS_DOCUMENT.value()); Document documentObject = createMockedCmisObject( new Object[][] { {PropertyIds.NAME, "Name", "A document name.txt"}, {PropertyIds.CONTENT_STREAM_LENGTH, "Content Stream Length", "210"}, {PropertyIds.BASE_TYPE_ID, "Base Type Id", "cmis:document"}, {PropertyIds.OBJECT_TYPE_ID, "Object Type Id", "cmis:document"}, {PropertyIds.LAST_MODIFICATION_DATE, "Last Modification Date", new Date(0)}, {PropertyIds.OBJECT_TYPE_ID, "Object Type Id", "cmis:document"}, {PropertyIds.CONTENT_STREAM_MIME_TYPE, "Content Stream Mime Type", "text/plain"}, {PropertyIds.OBJECT_ID, "Object Type Id", TEST_DOCUMENT_ID} }, Document.class); when(documentObject.getId()).thenReturn(TEST_DOCUMENT_ID); when(documentObject.getBaseType()).thenReturn(documentObjectType); return documentObject; }
/** * Returns the singleton application object matching the given {@code applicationClass} within * the given {@code database}. */ @SuppressWarnings("unchecked") public static <T extends Application> T getInstanceUsing( Class<T> applicationClass, Database database) { ObjectType type = database.getEnvironment().getTypeByClass(applicationClass); Query<T> query = Query.from(applicationClass).where("_type = ?", type.getId()).using(database); T app = query.first(); if (app == null) { DistributedLock lock = DistributedLock.Static.getInstance(database, applicationClass.getName()); lock.lock(); try { app = query.clone().noCache().first(); if (app == null) { app = (T) type.createObject(null); app.setName(type.getDisplayName()); app.saveImmediately(); return app; } } finally { lock.unlock(); } } String oldName = app.getName(); String newName = type.getDisplayName(); if (!ObjectUtils.equals(oldName, newName)) { app.setName(newName); app.save(); } return app; }
public static void writeContents( Database database, BootstrapPackage pkg, Set<ObjectType> additionalTypes, Writer writer, String projectName) throws IOException { boolean first = true; boolean needsObjectTypeMap = false; Set<ObjectType> typeMaps = new HashSet<ObjectType>(); ObjectType objType = database.getEnvironment().getTypeByClass(ObjectType.class); Set<ObjectType> exportTypes = new HashSet<ObjectType>(); Query<?> query = Query.fromAll().using(database); Set<ObjectType> allTypeMappableTypes = new HashSet<ObjectType>(); Set<UUID> concreteTypeIds = new HashSet<UUID>(); for (ObjectType type : database.getEnvironment().getTypes()) { if (!type.as(TypeData.class).getTypeMappableGroups().isEmpty() && type.as(TypeData.class).getTypeMappableUniqueKey() != null) { allTypeMappableTypes.add(type); } } // Package: writer.write(PACKAGE_NAME_HEADER + ": "); writer.write(pkg.getName()); writer.write('\n'); // Project: writer.write(PROJECT_HEADER + ": "); writer.write(projectName); writer.write('\n'); // Date: writer.write(DATE_HEADER + ": "); writer.write(new DateTime().toString("yyyy-MM-dd HH:mm:ss z")); writer.write('\n'); // Types: writer.write(TYPES_HEADER + ": "); if (pkg.isInit()) { writer.write(ALL_TYPES_HEADER_VALUE); writer.write('\n'); } else { exportTypes.addAll(getAllTypes(database, pkg)); exportTypes.addAll(getAllTypes(database, additionalTypes)); for (ObjectType typeMappableType : allTypeMappableTypes) { GETTYPEMAPPABLETYPE: for (ObjectType type : exportTypes) { for (String group : typeMappableType.as(TypeData.class).getTypeMappableGroups()) { if (type.getGroups().contains(group)) { typeMaps.add(typeMappableType); break GETTYPEMAPPABLETYPE; } } } } GETOBJECTTYPE: for (ObjectType type : exportTypes) { for (ObjectField field : type.getFields()) { if (field.getTypes().contains(objType)) { needsObjectTypeMap = true; break GETOBJECTTYPE; } } } for (ObjectType exportType : exportTypes) { String clsName = exportType.getObjectClassName(); if (!ObjectUtils.isBlank(clsName)) { for (ObjectType concreteType : database.getEnvironment().getTypesByGroup(clsName)) { if (!concreteType.isAbstract()) { concreteTypeIds.add(concreteType.getId()); } } } } if (exportTypes.contains(objType)) { if (!first) { writer.write(','); } else { first = false; } writer.write(objType.getInternalName()); } for (ObjectType type : exportTypes) { if (type.equals(objType)) { continue; } if (!first) { writer.write(','); } else { first = false; } writer.write(type.getInternalName()); } writer.write('\n'); } // Determine if there are any fields that need references followed Map<UUID, Map<String, ObjectType>> followReferences = new HashMap<UUID, Map<String, ObjectType>>(); if (!pkg.isInit()) { for (ObjectType type : exportTypes) { for (String fieldName : type.as(TypeData.class).getFollowReferencesFields()) { ObjectField field = type.getField(fieldName); if (field != null) { for (ObjectType fieldType : field.getTypes()) { if (!exportTypes.contains(fieldType)) { if (!followReferences.containsKey(type.getId())) { followReferences.put(type.getId(), new HashMap<String, ObjectType>()); } followReferences.get(type.getId()).put(fieldName, fieldType); } } } } } } if (!typeMaps.isEmpty()) { for (ObjectType typeMapType : typeMaps) { String clsName = typeMapType.getObjectClassName(); if (!ObjectUtils.isBlank(clsName)) { for (ObjectType type : database.getEnvironment().getTypesByGroup(clsName)) { concreteTypeIds.remove(type.getId()); } } } } // Mapping Types: if (pkg.isInit() || needsObjectTypeMap || !typeMaps.isEmpty()) { first = true; writer.write(TYPE_MAP_HEADER + ": "); if (pkg.isInit() || needsObjectTypeMap) { writer.write(objType.getInternalName()); writer.write("/internalName"); first = false; } for (ObjectType typeMapType : typeMaps) { if (!first) { writer.write(','); } else { first = false; } writer.write(typeMapType.getInternalName()); writer.write('/'); writer.write(typeMapType.as(TypeData.class).getTypeMappableUniqueKey()); } writer.write('\n'); } // Row Count: Long count = 0L; try { if (concreteTypeIds.isEmpty()) { count = Query.fromAll().using(database).noCache().count(); } else { for (UUID concreteTypeId : concreteTypeIds) { long concreteCount = Query.fromAll() .using(database) .noCache() .where("_type = ?", concreteTypeId) .count(); count = count + concreteCount; } if (needsObjectTypeMap) { long objectCount = Query.fromAll().using(database).noCache().where("_type = ?", objType).count(); count = count + objectCount; } if (!typeMaps.isEmpty()) { for (ObjectType typeMapType : typeMaps) { long typeMapCount = Query.fromAll().using(database).noCache().where("_type = ?", typeMapType).count(); count = count + typeMapCount; } } } writer.write(ROW_COUNT_HEADER + ": "); writer.write(ObjectUtils.to(String.class, count)); writer.write('\n'); } catch (RuntimeException e) { // Count query timed out. Just don't write the row count header. count = null; } // blank line between headers and data writer.write('\n'); writer.flush(); // ObjectType records first if (exportTypes.isEmpty() || exportTypes.contains(objType) || needsObjectTypeMap) { for (Object r : Query.fromType(objType) .using(database) .noCache() .resolveToReferenceOnly() .iterable(100)) { writer.write(ObjectUtils.toJson(((Recordable) r).getState().getSimpleValues(true))); writer.write('\n'); } } // Then other mapping types for (ObjectType typeMapType : typeMaps) { for (Object r : Query.fromType(typeMapType) .using(database) .noCache() .resolveToReferenceOnly() .iterable(100)) { writer.write(ObjectUtils.toJson(((Recordable) r).getState().getSimpleValues(true))); writer.write('\n'); } } // Then everything else if (pkg.isInit()) { concreteTypeIds.clear(); // should already be empty concreteTypeIds.add(null); } UUID lastTypeId = null; Set<UUID> seenIds = new HashSet<UUID>(); query.getOptions().put(SqlDatabase.USE_JDBC_FETCH_SIZE_QUERY_OPTION, false); for (UUID typeId : concreteTypeIds) { Query<?> concreteQuery = query.clone(); if (typeId != null) { concreteQuery.where("_type = ?", typeId); } for (Object o : concreteQuery.noCache().resolveToReferenceOnly().iterable(100)) { if (o instanceof Recordable) { Recordable r = (Recordable) o; writer.write(ObjectUtils.toJson(r.getState().getSimpleValues(true))); writer.write('\n'); if (!pkg.isInit()) { if (lastTypeId == null || !lastTypeId.equals(r.getState().getTypeId())) { seenIds.clear(); } else if (seenIds.size() > MAX_SEEN_REFERENCE_IDS_SIZE) { seenIds.clear(); } lastTypeId = r.getState().getTypeId(); Map<String, ObjectType> followReferencesFieldMap; if ((followReferencesFieldMap = followReferences.get(r.getState().getTypeId())) != null) { for (Map.Entry<String, ObjectType> entry : followReferencesFieldMap.entrySet()) { Object reference = r.getState().getRawValue(entry.getKey()); Set<UUID> referenceIds = new HashSet<UUID>(); if (reference instanceof Collection) { for (Object referenceObj : ((Collection<?>) reference)) { if (referenceObj instanceof Recordable) { UUID referenceUUID = ObjectUtils.to( UUID.class, ((Recordable) referenceObj).getState().getId()); if (referenceUUID != null) { if (!seenIds.contains(referenceUUID)) { referenceIds.add(referenceUUID); } } } } } else if (reference instanceof Recordable) { UUID referenceUUID = ObjectUtils.to(UUID.class, ((Recordable) reference).getState().getId()); if (referenceUUID != null) { if (!seenIds.contains(referenceUUID)) { referenceIds.add(referenceUUID); } } } if (!referenceIds.isEmpty()) { for (Object ref : Query.fromType(entry.getValue()) .noCache() .using(database) .where("_id = ?", referenceIds) .selectAll()) { if (ref instanceof Recordable) { Recordable refr = (Recordable) ref; seenIds.add(refr.getState().getId()); writer.write(ObjectUtils.toJson(refr.getState().getSimpleValues(true))); writer.write('\n'); } } } } } } } } } writer.flush(); }