use of com.unboundid.ldap.sdk.ReadOnlyEntry in project ldapsdk by pingidentity.
the class GenerateSourceFromSchema method generateSourceFile.
/**
* Generates the source file using the information in the provided schema.
*
* @param schema The schema to use to generate the source file.
* @param terse Indicates whether to use terse mode when generating the
* source file. If this is {@code true}, then all optional
* elements will be omitted from annotations.
*
* @return A result code obtained for the processing.
*/
@NotNull()
private ResultCode generateSourceFile(@NotNull final Schema schema, final boolean terse) {
// Retrieve and process the structural object class.
final TreeMap<String, AttributeTypeDefinition> requiredAttrs = new TreeMap<>();
final TreeMap<String, AttributeTypeDefinition> optionalAttrs = new TreeMap<>();
final TreeMap<String, TreeSet<String>> requiredAttrOCs = new TreeMap<>();
final TreeMap<String, TreeSet<String>> optionalAttrOCs = new TreeMap<>();
final TreeMap<String, String> types = new TreeMap<>();
final String structuralClassName = structuralClassArg.getValue();
final ObjectClassDefinition structuralOC = schema.getObjectClass(structuralClassName);
if (structuralOC == null) {
err(ERR_GEN_SOURCE_STRUCTURAL_CLASS_NOT_FOUND.get(structuralClassName));
return ResultCode.PARAM_ERROR;
}
if (structuralOC.getObjectClassType(schema) != ObjectClassType.STRUCTURAL) {
err(ERR_GEN_SOURCE_STRUCTURAL_CLASS_NOT_STRUCTURAL.get(structuralClassName));
return ResultCode.PARAM_ERROR;
}
processObjectClass(structuralOC, schema, requiredAttrs, requiredAttrOCs, optionalAttrs, optionalAttrOCs, types);
// Retrieve and process the auxiliary object classes.
final TreeMap<String, ObjectClassDefinition> auxiliaryOCs = new TreeMap<>();
if (auxiliaryClassArg.isPresent()) {
for (final String s : auxiliaryClassArg.getValues()) {
final ObjectClassDefinition oc = schema.getObjectClass(s);
if (oc == null) {
err(ERR_GEN_SOURCE_AUXILIARY_CLASS_NOT_FOUND.get(s));
return ResultCode.PARAM_ERROR;
}
if (oc.getObjectClassType(schema) != ObjectClassType.AUXILIARY) {
err(ERR_GEN_SOURCE_AUXILIARY_CLASS_NOT_AUXILIARY.get(s));
return ResultCode.PARAM_ERROR;
}
auxiliaryOCs.put(StaticUtils.toLowerCase(s), oc);
processObjectClass(oc, schema, requiredAttrs, requiredAttrOCs, optionalAttrs, optionalAttrOCs, types);
}
}
// Determine the appropriate set of superior object classes.
final TreeMap<String, ObjectClassDefinition> superiorOCs = new TreeMap<>();
for (final ObjectClassDefinition s : structuralOC.getSuperiorClasses(schema, true)) {
superiorOCs.put(StaticUtils.toLowerCase(s.getNameOrOID()), s);
}
for (final ObjectClassDefinition d : auxiliaryOCs.values()) {
for (final ObjectClassDefinition s : d.getSuperiorClasses(schema, true)) {
superiorOCs.put(StaticUtils.toLowerCase(s.getNameOrOID()), s);
}
}
superiorOCs.remove(StaticUtils.toLowerCase(structuralClassName));
for (final String s : auxiliaryOCs.keySet()) {
superiorOCs.remove(s);
}
// Retrieve and process the operational attributes.
final TreeMap<String, AttributeTypeDefinition> operationalAttrs = new TreeMap<>();
if (operationalAttributeArg.isPresent()) {
for (final String s : operationalAttributeArg.getValues()) {
final AttributeTypeDefinition d = schema.getAttributeType(s);
if (d == null) {
err(ERR_GEN_SOURCE_OPERATIONAL_ATTRIBUTE_NOT_DEFINED.get(s));
return ResultCode.PARAM_ERROR;
} else if (!d.isOperational()) {
err(ERR_GEN_SOURCE_OPERATIONAL_ATTRIBUTE_NOT_OPERATIONAL.get(s));
return ResultCode.PARAM_ERROR;
} else {
final String lowerName = StaticUtils.toLowerCase(s);
operationalAttrs.put(lowerName, d);
types.put(lowerName, getJavaType(schema, d));
}
}
}
// Make sure all of the configured RDN attributes are allowed by at least
// one of the associated object classes.
final TreeSet<String> rdnAttrs = new TreeSet<>();
for (final String s : rdnAttributeArg.getValues()) {
final AttributeTypeDefinition d = schema.getAttributeType(s);
if (d == null) {
err(ERR_GEN_SOURCE_RDN_ATTRIBUTE_NOT_DEFINED.get(s));
return ResultCode.PARAM_ERROR;
}
final String lowerName = StaticUtils.toLowerCase(d.getNameOrOID());
rdnAttrs.add(lowerName);
if (requiredAttrs.containsKey(lowerName)) {
// No action required.
} else if (optionalAttrs.containsKey(lowerName)) {
// Move the attribute to the required set.
requiredAttrs.put(lowerName, optionalAttrs.remove(lowerName));
requiredAttrOCs.put(lowerName, optionalAttrOCs.remove(lowerName));
} else {
err(ERR_GEN_SOURCE_RDN_ATTRIBUTE_NOT_DEFINED.get(s));
return ResultCode.PARAM_ERROR;
}
}
// Make sure all of the configured lazily-loaded attributes are allowed by
// at least one of the associated object classes or matches a configured
// operational attribute.
final TreeSet<String> lazyAttrs = new TreeSet<>();
for (final String s : lazyAttributeArg.getValues()) {
final AttributeTypeDefinition d = schema.getAttributeType(s);
if (d == null) {
err(ERR_GEN_SOURCE_LAZY_ATTRIBUTE_NOT_DEFINED.get(s));
return ResultCode.PARAM_ERROR;
}
final String lowerName = StaticUtils.toLowerCase(d.getNameOrOID());
lazyAttrs.add(lowerName);
if (requiredAttrs.containsKey(lowerName) || optionalAttrs.containsKey(lowerName) || operationalAttrs.containsKey(lowerName)) {
// No action required.
} else {
err(ERR_GEN_SOURCE_LAZY_ATTRIBUTE_NOT_ALLOWED.get(s));
return ResultCode.PARAM_ERROR;
}
}
final String className;
if (classNameArg.isPresent()) {
className = classNameArg.getValue();
final StringBuilder invalidReason = new StringBuilder();
if (!PersistUtils.isValidJavaIdentifier(className, invalidReason)) {
err(ERR_GEN_SOURCE_INVALID_CLASS_NAME.get(className, invalidReason.toString()));
return ResultCode.PARAM_ERROR;
}
} else {
className = StaticUtils.capitalize(PersistUtils.toJavaIdentifier(structuralClassName));
}
final File sourceFile = new File(outputDirectoryArg.getValue(), className + ".java");
final PrintWriter writer;
try {
writer = new PrintWriter(new FileWriter(sourceFile));
} catch (final Exception e) {
Debug.debugException(e);
err(ERR_GEN_SOURCE_CANNOT_CREATE_WRITER.get(sourceFile.getAbsolutePath(), StaticUtils.getExceptionMessage(e)));
return ResultCode.LOCAL_ERROR;
}
if (packageNameArg.isPresent()) {
final String packageName = packageNameArg.getValue();
if (!packageName.isEmpty()) {
writer.println("package " + packageName + ';');
writer.println();
writer.println();
writer.println();
}
}
boolean javaImports = false;
if (needArrays) {
writer.println("import " + Arrays.class.getName() + ';');
javaImports = true;
}
if (needDate) {
writer.println("import " + Date.class.getName() + ';');
javaImports = true;
}
if (javaImports) {
writer.println();
}
if (needDN) {
writer.println("import " + DN.class.getName() + ';');
}
writer.println("import " + Entry.class.getName() + ';');
writer.println("import " + Filter.class.getName() + ';');
if (needDN) {
writer.println("import " + LDAPException.class.getName() + ';');
writer.println("import " + LDAPInterface.class.getName() + ';');
}
writer.println("import " + ReadOnlyEntry.class.getName() + ';');
writer.println("import " + DefaultObjectEncoder.class.getName() + ';');
writer.println("import " + FieldInfo.class.getName() + ';');
writer.println("import " + FilterUsage.class.getName() + ';');
writer.println("import " + LDAPEntryField.class.getName() + ';');
writer.println("import " + LDAPField.class.getName() + ';');
writer.println("import " + LDAPObject.class.getName() + ';');
writer.println("import " + LDAPObjectHandler.class.getName() + ';');
writer.println("import " + LDAPPersister.class.getName() + ';');
writer.println("import " + LDAPPersistException.class.getName() + ';');
if (needPersistedObjects) {
writer.println("import " + PersistedObjects.class.getName() + ';');
}
writer.println("import " + PersistFilterType.class.getName() + ';');
if (needDN) {
writer.println("import " + PersistUtils.class.getName() + ';');
}
writer.println();
writer.println();
writer.println();
writer.println("/**");
writer.println(" * This class provides an implementation of an object " + "that can be used to");
writer.println(" * represent " + structuralClassName + " objects in the directory.");
writer.println(" * It was generated by the " + getToolName() + " tool provided with the");
writer.println(" * UnboundID LDAP SDK for Java. It " + "may be customized as desired to better suit");
writer.println(" * your needs.");
writer.println(" */");
writer.println("@LDAPObject(structuralClass=\"" + structuralClassName + "\",");
switch(auxiliaryOCs.size()) {
case 0:
// No action required.
break;
case 1:
writer.println(" auxiliaryClass=\"" + auxiliaryOCs.values().iterator().next().getNameOrOID() + "\",");
break;
default:
final Iterator<ObjectClassDefinition> iterator = auxiliaryOCs.values().iterator();
writer.println(" auxiliaryClass={ \"" + iterator.next().getNameOrOID() + "\",");
while (iterator.hasNext()) {
final String ocName = iterator.next().getNameOrOID();
if (iterator.hasNext()) {
writer.println(" \"" + ocName + "\",");
} else {
writer.println(" \"" + ocName + "\" },");
}
}
break;
}
switch(superiorOCs.size()) {
case 0:
// No action required.
break;
case 1:
writer.println(" superiorClass=\"" + superiorOCs.values().iterator().next().getNameOrOID() + "\",");
break;
default:
final Iterator<ObjectClassDefinition> iterator = superiorOCs.values().iterator();
writer.println(" superiorClass={ \"" + iterator.next().getNameOrOID() + "\",");
while (iterator.hasNext()) {
final String ocName = iterator.next().getNameOrOID();
if (iterator.hasNext()) {
writer.println(" \"" + ocName + "\",");
} else {
writer.println(" \"" + ocName + "\" },");
}
}
break;
}
if (defaultParentDNArg.isPresent()) {
writer.println(" defaultParentDN=\"" + defaultParentDNArg.getValue() + "\",");
}
writer.println(" postDecodeMethod=\"doPostDecode\",");
writer.println(" postEncodeMethod=\"doPostEncode\")");
writer.println("public class " + className);
writer.println("{");
if (!terse) {
writer.println(" /*");
writer.println(" * NOTE: This class includes a number of annotation " + "elements which are not");
writer.println(" * required but have been provided to make it easier " + "to edit the resulting");
writer.println(" * source code. If you want to exclude these " + "unnecessary annotation");
writer.println(" * elements, use the '--terse' command-line argument.");
writer.println(" */");
writer.println();
writer.println();
writer.println();
}
writer.println(" // The field to use to hold a read-only copy of the " + "associated entry.");
writer.println(" @LDAPEntryField()");
writer.println(" private ReadOnlyEntry ldapEntry;");
// attributes, and finally any operational attributes.
for (final String lowerName : rdnAttrs) {
final AttributeTypeDefinition d = requiredAttrs.get(lowerName);
final TreeSet<String> ocNames = requiredAttrOCs.get(lowerName);
writeField(writer, d, types.get(lowerName), ocNames, true, true, structuralClassName, false, terse);
}
for (final String lowerName : requiredAttrs.keySet()) {
if (rdnAttrs.contains(lowerName)) {
continue;
}
final AttributeTypeDefinition d = requiredAttrs.get(lowerName);
final TreeSet<String> ocNames = requiredAttrOCs.get(lowerName);
writeField(writer, d, types.get(lowerName), ocNames, false, true, structuralClassName, lazyAttrs.contains(lowerName), terse);
}
for (final String lowerName : optionalAttrs.keySet()) {
final AttributeTypeDefinition d = optionalAttrs.get(lowerName);
final TreeSet<String> ocNames = optionalAttrOCs.get(lowerName);
writeField(writer, d, types.get(lowerName), ocNames, false, false, structuralClassName, lazyAttrs.contains(lowerName), terse);
}
for (final String lowerName : operationalAttrs.keySet()) {
final AttributeTypeDefinition d = operationalAttrs.get(lowerName);
final TreeSet<String> ocNames = EMPTY_TREE_SET;
writeField(writer, d, types.get(lowerName), ocNames, false, false, structuralClassName, lazyAttrs.contains(lowerName), terse);
}
// Add the default constructor.
writer.println();
writer.println();
writer.println();
writer.println(" /**");
writer.println(" * Creates a new instance of this object. All fields " + "will be uninitialized,");
writer.println(" * so the setter methods should be used to assign " + "values to them.");
writer.println(" */");
writer.println(" public " + className + "()");
writer.println(" {");
writer.println(" // No initialization will be performed by default. " + "Note that if you set");
writer.println(" // values for any fields marked with an @LDAPField, " + "@LDAPDNField, or");
writer.println(" // @LDAPEntryField annotation, they will be " + "overwritten in the course of");
writer.println(" // decoding initializing this object from an LDAP " + "entry.");
writer.println(" }");
// Add a static decode method that can create an instance of the object
// from a given entry.
writer.println();
writer.println();
writer.println();
writer.println(" /**");
writer.println(" * Creates a new " + className + " object decoded");
writer.println(" * from the provided entry.");
writer.println(" *");
writer.println(" * @param entry The entry to be decoded.");
writer.println(" *");
writer.println(" * @return The decoded " + className + " object.");
writer.println(" *");
writer.println(" * @throws LDAPPersistException If a problem occurs " + "while attempting to");
writer.println(" * decode the provided " + "entry.");
writer.println(" */");
writer.println(" public static " + className + " decode(final Entry entry)");
writer.println(" throws LDAPPersistException");
writer.println(" {");
writer.println(" return getPersister().decode(entry);");
writer.println(" }");
// Add the getPersister method.
writer.println("");
writer.println("");
writer.println("");
writer.println(" /**");
writer.println(" * Retrieves an {@code LDAPPersister} instance that " + "may be used to interact");
writer.println(" * with objects of this type.");
writer.println(" *");
writer.println(" * @return An {@code LDAPPersister} instance that may " + "be used to interact");
writer.println(" * with objects of this type.");
writer.println(" *");
writer.println(" * @throws LDAPPersistException If a problem occurs " + "while creating the");
writer.println(" * " + "{@code LDAPPersister} instance.");
writer.println(" */");
writer.println(" public static LDAPPersister<" + className + "> getPersister()");
writer.println(" throws LDAPPersistException");
writer.println(" {");
writer.println(" return LDAPPersister.getInstance(" + className + ".class);");
writer.println(" }");
// Add the post-decode and post-encode methods.
writer.println();
writer.println();
writer.println();
writer.println(" /**");
writer.println(" * Performs any processing that may be necessary after " + "initializing this");
writer.println(" * object from an LDAP entry.");
writer.println(" *");
writer.println(" * @throws LDAPPersistException If there is a " + "problem with the object after");
writer.println(" * it has been decoded " + "from an LDAP entry.");
writer.println(" */");
writer.println(" private void doPostDecode()");
writer.println(" throws LDAPPersistException");
writer.println(" {");
writer.println(" // No processing is needed by default. You may " + "provide an implementation");
writer.println(" // for this method if custom post-decode processing " + "is needed.");
writer.println(" }");
writer.println();
writer.println();
writer.println();
writer.println(" /**");
writer.println(" * Performs any processing that may be necessary after " + "encoding this object");
writer.println(" * to an LDAP entry.");
writer.println(" *");
writer.println(" * @param entry The entry that has been generated. " + "It may be altered if");
writer.println(" * desired.");
writer.println(" *");
writer.println(" * @throws LDAPPersistException If the generated " + "entry should not be used.");
writer.println(" */");
writer.println(" private void doPostEncode(final Entry entry)");
writer.println(" throws LDAPPersistException");
writer.println(" {");
writer.println(" // No processing is needed by default. You may " + "provide an implementation");
writer.println(" // for this method if custom post-encode processing " + "is needed.");
writer.println(" }");
// Add a method for getting a read-only copy of the associated entry.
writer.println();
writer.println();
writer.println();
writer.println(" /**");
writer.println(" * Retrieves a read-only copy of the entry with which " + "this object is");
writer.println(" * associated, if it is available. It will only be " + "available if this object");
writer.println(" * was decoded from or encoded to an LDAP entry.");
writer.println(" *");
writer.println(" * @return A read-only copy of the entry with which " + "this object is");
writer.println(" * associated, or {@code null} if it is not " + "available.");
writer.println(" */");
writer.println(" public ReadOnlyEntry getLDAPEntry()");
writer.println(" {");
writer.println(" return ldapEntry;");
writer.println(" }");
// Add a method for getting the DN of the associated entry.
writer.println();
writer.println();
writer.println();
writer.println(" /**");
writer.println(" * Retrieves the DN of the entry with which this " + "object is associated, if it");
writer.println(" * is available. It will only be available if this " + "object was decoded from or");
writer.println(" * encoded to an LDAP entry.");
writer.println(" *");
writer.println(" * @return The DN of the entry with which this object " + "is associated, or");
writer.println(" * {@code null} if it is not available.");
writer.println(" */");
writer.println(" public String getLDAPEntryDN()");
writer.println(" {");
writer.println(" if (ldapEntry == null)");
writer.println(" {");
writer.println(" return null;");
writer.println(" }");
writer.println(" else");
writer.println(" {");
writer.println(" return ldapEntry.getDN();");
writer.println(" }");
writer.println(" }");
// the optional attributes.
for (final String lowerName : rdnAttrs) {
final AttributeTypeDefinition d = requiredAttrs.get(lowerName);
writeFieldMethods(writer, d, types.get(lowerName), true);
}
for (final String lowerName : requiredAttrs.keySet()) {
if (rdnAttrs.contains(lowerName)) {
continue;
}
final AttributeTypeDefinition d = requiredAttrs.get(lowerName);
writeFieldMethods(writer, d, types.get(lowerName), true);
}
for (final String lowerName : optionalAttrs.keySet()) {
final AttributeTypeDefinition d = optionalAttrs.get(lowerName);
writeFieldMethods(writer, d, types.get(lowerName), true);
}
for (final String lowerName : operationalAttrs.keySet()) {
final AttributeTypeDefinition d = operationalAttrs.get(lowerName);
writeFieldMethods(writer, d, types.get(lowerName), false);
}
writeToString(writer, className, requiredAttrs.values(), optionalAttrs.values(), operationalAttrs.values());
writer.println("}");
writer.println();
writer.close();
return ResultCode.SUCCESS;
}
use of com.unboundid.ldap.sdk.ReadOnlyEntry in project ldapsdk by pingidentity.
the class SoftDeletedEntry method getUndeletedEntry.
/**
* Retrieves a copy of the original entry as it appeared before the soft
* delete operation was processed. It will have its original DN and all
* soft delete metadata attributes and auxiliary object class removed.
*
* @return A copy of the original entry as it appeared before the soft delete
* operation was processed.
*/
@NotNull()
public ReadOnlyEntry getUndeletedEntry() {
final Entry e = duplicate();
e.setDN(softDeleteFromDN);
e.removeAttributeValue("objectClass", OC_SOFT_DELETED_ENTRY);
e.removeAttribute(ATTR_SOFT_DELETE_FROM_DN);
e.removeAttribute(ATTR_SOFT_DELETE_TIMESTAMP);
e.removeAttribute(ATTR_SOFT_DELETE_REQUESTER_DN);
e.removeAttribute(ATTR_SOFT_DELETE_REQUESTER_IP_ADDRESS);
return new ReadOnlyEntry(e);
}
use of com.unboundid.ldap.sdk.ReadOnlyEntry in project ldapsdk by pingidentity.
the class AuditLogMessage method decodeCommentedEntry.
/**
* Decodes an entry (or list of attributes) from the commented header
* contained in the log message lines.
*
* @param header The header line that appears before the encoded
* entry.
* @param logMessageLines The lines that comprise the audit log message.
* @param entryDN The DN to use for the entry that is read. It
* should be {@code null} if the commented entry
* includes a DN, and non-{@code null} if the
* commented entry does not include a DN.
*
* @return The entry that was decoded from the commented header, or
* {@code null} if it is not included in the header or if it cannot
* be decoded. If the commented entry does not include a DN, then
* the DN of the entry returned will be the null DN.
*/
@Nullable()
protected static ReadOnlyEntry decodeCommentedEntry(@NotNull final String header, @NotNull final List<String> logMessageLines, @Nullable final String entryDN) {
List<String> ldifLines = null;
StringBuilder invalidLDAPNameReason = null;
for (final String line : logMessageLines) {
final String uncommentedLine;
if (line.startsWith("# ")) {
uncommentedLine = line.substring(2);
} else {
break;
}
if (ldifLines == null) {
if (uncommentedLine.equalsIgnoreCase(header)) {
ldifLines = new ArrayList<>(logMessageLines.size());
if (entryDN != null) {
ldifLines.add("dn: " + entryDN);
}
}
} else {
final int colonPos = uncommentedLine.indexOf(':');
if (colonPos <= 0) {
break;
}
if (invalidLDAPNameReason == null) {
invalidLDAPNameReason = new StringBuilder();
}
final String potentialAttributeName = uncommentedLine.substring(0, colonPos);
if (PersistUtils.isValidLDAPName(potentialAttributeName, invalidLDAPNameReason)) {
ldifLines.add(uncommentedLine);
} else {
break;
}
}
}
if (ldifLines == null) {
return null;
}
try {
final String[] ldifLineArray = ldifLines.toArray(StaticUtils.NO_STRINGS);
final Entry ldifEntry = LDIFReader.decodeEntry(ldifLineArray);
return new ReadOnlyEntry(ldifEntry);
} catch (final Exception e) {
Debug.debugException(e);
return null;
}
}
use of com.unboundid.ldap.sdk.ReadOnlyEntry in project ldapsdk by pingidentity.
the class LDAPDiffProcessor method process.
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
public LDAPDiffProcessorResult process(@NotNull final LDAPDiffCompactDN compactDN) throws LDAPException {
// Convert the provided compact DN to a full DN.
final DN dn = compactDN.toDN(baseDN, schema);
final String dnString = dn.toString();
// Retrieve the entry from the source and target servers.
final ReadOnlyEntry sourceEntry;
try {
sourceEntry = sourcePool.getEntry(dnString, attributes);
} catch (final LDAPException e) {
Debug.debugException(e);
throw new LDAPException(e.getResultCode(), ERR_LDAP_DIFF_PROCESSOR_ERROR_GETTING_ENTRY_FROM_SOURCE.get(dnString, StaticUtils.getExceptionMessage(e)), e);
}
final ReadOnlyEntry targetEntry;
try {
targetEntry = targetPool.getEntry(dnString, attributes);
} catch (final LDAPException e) {
Debug.debugException(e);
throw new LDAPException(e.getResultCode(), ERR_LDAP_DIFF_PROCESSOR_ERROR_GETTING_ENTRY_FROM_TARGET.get(dnString, StaticUtils.getExceptionMessage(e)), e);
}
// Otherwise, it needs to be added.
if (sourceEntry == null) {
if (targetEntry == null) {
return LDAPDiffProcessorResult.createEntryMissingResult(dnString);
} else {
return LDAPDiffProcessorResult.createAddResult(targetEntry);
}
}
// If the target entry is null, then the entry needs to be removed.
if (targetEntry == null) {
return LDAPDiffProcessorResult.createDeleteResult(sourceEntry);
}
// perform a diff to see if the entries are the same or different.
if (missingOnly) {
return LDAPDiffProcessorResult.createNoChangesResult(sourceEntry.getDN());
} else {
final List<Modification> mods = Entry.diff(sourceEntry, targetEntry, DO_NOT_IGNORE_RDN, USE_REVERSIBLE_MODE, byteForByte);
if (mods.isEmpty()) {
return LDAPDiffProcessorResult.createNoChangesResult(sourceEntry.getDN());
} else {
return LDAPDiffProcessorResult.createModifyResult(sourceEntry.getDN(), mods);
}
}
}
Aggregations