/* * Copyright 2010 Outerthought bvba * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.lilyproject.tools.import_.core; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.lilyproject.repository.api.FieldTypeEntry; import org.lilyproject.repository.api.QName; import org.lilyproject.repository.api.RecordType; import org.lilyproject.repository.api.RecordTypeExistsException; import org.lilyproject.repository.api.RecordTypeNotFoundException; import org.lilyproject.repository.api.RepositoryException; import org.lilyproject.repository.api.SchemaId; import org.lilyproject.repository.api.TypeManager; import static org.lilyproject.tools.import_.core.ImportMode.CREATE; import static org.lilyproject.tools.import_.core.ImportMode.CREATE_OR_UPDATE; import static org.lilyproject.tools.import_.core.ImportMode.UPDATE; public class RecordTypeImport { private RecordTypeImport() { } public static ImportResult<RecordType> importRecordType(RecordType newRecordType, ImportMode impMode, IdentificationMode idMode, QName identifyingName, boolean refreshSubtypes, TypeManager typeManager) throws RepositoryException, InterruptedException { if (idMode == IdentificationMode.ID && impMode == CREATE_OR_UPDATE) { throw new IllegalArgumentException("The combination of import mode " + CREATE_OR_UPDATE + " and identification mode " + IdentificationMode.ID + " is not possible."); } int loopCount = 0; while (true) { if (loopCount > 1) { // We should never arrive here throw new RuntimeException("Unexpected situation: when we tried to update the record type, " + "it did not exist, when we tried to create the record type, it exists, and then when we retry " + "to update, it does not exist after all."); } if (impMode == UPDATE || impMode == CREATE_OR_UPDATE) { RecordType oldRecordType = null; try { if (idMode == IdentificationMode.ID) { oldRecordType = typeManager.getRecordTypeById(newRecordType.getId(), null); } else { oldRecordType = typeManager.getRecordTypeByName(identifyingName, null); } } catch (RecordTypeNotFoundException e) { if (impMode == UPDATE) { return ImportResult.cannotUpdateDoesNotExist(); } } if (oldRecordType != null) { boolean updated = false; // Update field entries Set<FieldTypeEntry> oldFieldTypeEntries = new HashSet<FieldTypeEntry>(oldRecordType.getFieldTypeEntries()); Set<FieldTypeEntry> newFieldTypeEntries = new HashSet<FieldTypeEntry>(newRecordType.getFieldTypeEntries()); if (!newFieldTypeEntries.equals(oldFieldTypeEntries)) { updated = true; oldRecordType.getFieldTypeEntries().clear(); for (FieldTypeEntry entry : newFieldTypeEntries) { oldRecordType.addFieldTypeEntry(entry); } } // Update supertypes Map<SchemaId, Long> oldSupertypes = oldRecordType.getSupertypes(); Map<SchemaId, Long> newSupertypes = newRecordType.getSupertypes(); // Resolve any 'null' versions to actual version numbers, otherwise we are unable to compare // with the old state. for (Map.Entry<SchemaId, Long> entry : newSupertypes.entrySet()) { if (entry.getValue() == null) { entry.setValue(typeManager.getRecordTypeById(entry.getKey(), null).getVersion()); } } if (!oldSupertypes.equals(newSupertypes)) { updated = true; oldRecordType.getSupertypes().clear(); for (Map.Entry<SchemaId, Long> entry : newSupertypes.entrySet()) { oldRecordType.addSupertype(entry.getKey(), entry.getValue()); } } // Update name QName oldName = oldRecordType.getName(); QName newName = newRecordType.getName(); if (!oldName.equals(newName)) { updated = true; oldRecordType.setName(newName); } if (updated) { oldRecordType = typeManager.updateRecordType(oldRecordType, refreshSubtypes); return ImportResult.updated(oldRecordType); } else { return ImportResult.upToDate(oldRecordType); } } } if (impMode == UPDATE) { // We should never arrive here, update is handled above throw new RuntimeException("Unexpected situation: in case of mode " + UPDATE + " we should not be here."); } try { RecordType createdRecordType = typeManager.createRecordType(newRecordType); return ImportResult.created(createdRecordType); } catch (RecordTypeExistsException e) { if (impMode == CREATE) { return ImportResult.cannotCreateExists(); } // and otherwise, the record type has been created since we last checked, so we now // loop again to the top to try to update it } loopCount++; } } }