/** Binds ODocument to POJO. */ @Override public void fromStream() { rwSpinLock.acquireWriteLock(); modificationCounter.get().increment(); try { // READ CURRENT SCHEMA VERSION final Integer schemaVersion = (Integer) document.field("schemaVersion"); if (schemaVersion == null) { OLogManager.instance() .error( this, "Database's schema is empty! Recreating the system classes and allow the opening of the database but double check the integrity of the database"); return; } else if (schemaVersion != CURRENT_VERSION_NUMBER && VERSION_NUMBER_V5 != schemaVersion) { // VERSION_NUMBER_V5 is needed for guarantee the compatibility to 2.0-M1 and 2.0-M2 no // changed associated with it // HANDLE SCHEMA UPGRADE throw new OConfigurationException( "Database schema is different. Please export your old database with the previous version of OrientDB and reimport it using the current one."); } properties.clear(); propertiesByNameType.clear(); List<ODocument> globalProperties = document.field("globalProperties"); boolean hasGlobalProperties = false; if (globalProperties != null) { hasGlobalProperties = true; for (ODocument oDocument : globalProperties) { OGlobalPropertyImpl prop = new OGlobalPropertyImpl(); prop.fromDocument(oDocument); ensurePropertiesSize(prop.getId()); properties.set(prop.getId(), prop); propertiesByNameType.put(prop.getName() + "|" + prop.getType().name(), prop); } } // REGISTER ALL THE CLASSES clustersToClasses.clear(); final Map<String, OClass> newClasses = new HashMap<String, OClass>(); OClassImpl cls; Collection<ODocument> storedClasses = document.field("classes"); for (ODocument c : storedClasses) { cls = new OClassImpl(this, c); cls.fromStream(); if (classes.containsKey(cls.getName().toLowerCase())) { cls = (OClassImpl) classes.get(cls.getName().toLowerCase()); cls.fromStream(c); } newClasses.put(cls.getName().toLowerCase(), cls); if (cls.getShortName() != null) newClasses.put(cls.getShortName().toLowerCase(), cls); addClusterClassMap(cls); } classes.clear(); classes.putAll(newClasses); // REBUILD THE INHERITANCE TREE List<String> superClassNames; String legacySuperClassName; List<OClass> superClasses; OClass superClass; for (ODocument c : storedClasses) { superClassNames = c.field("superClasses"); legacySuperClassName = c.field("superClass"); if (superClassNames == null) superClassNames = new ArrayList<String>(); if (legacySuperClassName != null && !superClassNames.contains(legacySuperClassName)) superClassNames.add(legacySuperClassName); if (!superClassNames.isEmpty()) { // HAS A SUPER CLASS or CLASSES cls = (OClassImpl) classes.get(((String) c.field("name")).toLowerCase()); superClasses = new ArrayList<OClass>(superClassNames.size()); for (String superClassName : superClassNames) { superClass = classes.get(superClassName.toLowerCase()); if (superClass == null) throw new OConfigurationException( "Super class '" + superClassName + "' was declared in class '" + cls.getName() + "' but was not found in schema. Remove the dependency or create the class to continue."); superClasses.add(superClass); } cls.setSuperClassesInternal(superClasses); } } if (!hasGlobalProperties) { if (getDatabase().getStorage().getUnderlying() instanceof OAbstractPaginatedStorage) saveInternal(); } } finally { version++; modificationCounter.get().decrement(); rwSpinLock.releaseWriteLock(); } }
private OClass createClassInternal( final String className, final int[] clusterIdsToAdd, final List<OClass> superClasses) throws ClusterIdsAreEmptyException { acquireSchemaWriteLock(); try { if (className == null || className.length() == 0) throw new OSchemaException("Found class name null or empty"); if (Character.isDigit(className.charAt(0))) throw new OSchemaException("Found invalid class name. Cannot start with numbers"); final Character wrongCharacter = checkClassNameIfValid(className); if (wrongCharacter != null) throw new OSchemaException( "Found invalid class name. Character '" + wrongCharacter + "' cannot be used in class name."); final ODatabaseDocumentInternal database = getDatabase(); final OStorage storage = database.getStorage(); checkEmbedded(storage); checkClustersAreAbsent(clusterIdsToAdd); final int[] clusterIds; if (clusterIdsToAdd == null || clusterIdsToAdd.length == 0) { throw new ClusterIdsAreEmptyException(); } else clusterIds = clusterIdsToAdd; database.checkSecurity(ORule.ResourceGeneric.SCHEMA, ORole.PERMISSION_CREATE); final String key = className.toLowerCase(); if (classes.containsKey(key)) throw new OSchemaException("Class " + className + " already exists in current database"); OClassImpl cls = new OClassImpl(this, className, clusterIds); classes.put(key, cls); if (superClasses != null && superClasses.size() > 0) { cls.setSuperClassesInternal(superClasses); for (OClass superClass : superClasses) { // UPDATE INDEXES final int[] clustersToIndex = superClass.getPolymorphicClusterIds(); final String[] clusterNames = new String[clustersToIndex.length]; for (int i = 0; i < clustersToIndex.length; i++) clusterNames[i] = database.getClusterNameById(clustersToIndex[i]); for (OIndex<?> index : superClass.getIndexes()) for (String clusterName : clusterNames) if (clusterName != null) database .getMetadata() .getIndexManager() .addClusterToIndex(clusterName, index.getName()); } } addClusterClassMap(cls); return cls; } finally { releaseSchemaWriteLock(); } }