/** * Returns the definition of the selected attribute / object class OID. * * @param schemaEntry The selected schema entry to search on. * @param type The type of the research. ("objectClasses" or "attributeTypes") * @param oid The OID of the element to search for. * @return The byte string definition of the element. */ private static ByteString getSchemaElement( final Entry schemaEntry, final String type, final String oid) { final Attribute attribute = schemaEntry.getAttribute(type); final MatchingRule mrule = CoreSchema.getObjectIdentifierFirstComponentMatchingRule(); Assertion assertion; try { assertion = mrule.getAssertion(ByteString.valueOfUtf8(oid)); for (final ByteString value : attribute) { final ByteString nvalue = mrule.normalizeAttributeValue(value); if (assertion.matches(nvalue).toBoolean()) { return value; } } } catch (DecodeException e) { throw new IllegalStateException(e); } throw new IllegalStateException(ERR_UPGRADE_UNKNOWN_OC_ATT.get(type, oid).toString()); }
/** * This task adds new attributes / object classes to the specified destination file. The new * attributes and object classes must be originally defined in the template file. * * @param templateFile The file in which the new attribute/object definition can be read. * @param destination The file where we want to add the new definitions. * @param attributes Those attributes needed to be inserted into the new destination file. * @param objectClasses Those object classes needed to be inserted into the new destination file. * @return An integer which represents each time an attribute / object class is inserted * successfully to the destination file. * @throws IOException If an unexpected IO error occurred while reading the entry. * @throws IllegalStateException Failure to find an attribute in the template schema indicates * either a programming error (e.g. typo in the attribute name) or template corruption. * Upgrade should stop. */ static int updateSchemaFile( final File templateFile, final File destination, final String[] attributes, final String[] objectClasses) throws IOException, IllegalStateException { int changeCount = 0; LDIFEntryReader templateReader = null; LDIFEntryReader destinationReader = null; LDIFEntryWriter destinationWriter = null; File copy = null; try { templateReader = new LDIFEntryReader(new FileInputStream(templateFile)); if (!templateReader.hasNext()) { // Unless template are corrupted, this should not happen. throw new IOException( ERR_UPGRADE_CORRUPTED_TEMPLATE.get(templateFile.getPath()).toString()); } final Entry templateSchemaEntry = templateReader.readEntry(); destinationReader = new LDIFEntryReader(new FileInputStream(destination)); if (!destinationReader.hasNext()) { // Unless template are corrupted, this should not happen. throw new IOException(ERR_UPGRADE_CORRUPTED_TEMPLATE.get(destination.getPath()).toString()); } final Entry destinationSchemaEntry = destinationReader.readEntry(); if (attributes != null) { for (final String att : attributes) { final ByteString attributeType = getSchemaElement(templateSchemaEntry, "attributeTypes", att); destinationSchemaEntry.getAttribute("attributeTypes").add(attributeType); changeCount++; logger.debug(LocalizableMessage.raw(String.format("Added %s", attributeType))); } } if (objectClasses != null) { for (final String oc : objectClasses) { final ByteString objectClass = getSchemaElement(templateSchemaEntry, "objectClasses", oc); destinationSchemaEntry.getAttribute("objectClasses").add(objectClass); changeCount++; logger.trace("Added %s", objectClass); } } // Then writes the new schema entry. copy = File.createTempFile("copySchema", ".tmp", destination.getParentFile()); final FileOutputStream fos = new FileOutputStream(copy); destinationWriter = new LDIFEntryWriter(fos); destinationWriter.setWrapColumn(79); // Copy comments to fos (get License and first comments only). writeFileHeaderComments(templateFile, destinationWriter); // Writes the entry after. destinationWriter.writeEntry(destinationSchemaEntry); } finally { // Readers and writer must be close before writing files. // This causes exceptions under windows OS. StaticUtils.close(templateReader, destinationReader, destinationWriter); } // Renames the copy to make it the new schema file. try { rename(copy, destination); } catch (IOException e) { logger.error(LocalizableMessage.raw(e.getMessage())); deleteRecursively(copy); throw e; } return changeCount; }