/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2006-2009 Sun Microsystems, Inc. */ package org.opends.server.tools.makeldif; import java.io.BufferedWriter; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import org.opends.server.core.DirectoryServer; import org.opends.server.types.*; import org.opends.server.util.LDIFException; import static org.opends.server.util.LDIFWriter.appendLDIFSeparatorAndValue; import static org.opends.server.util.LDIFWriter.writeLDIFLine; import static org.opends.server.util.StaticUtils.*; /** * This class defines an entry that is generated using a MakeLDIF branch or * template. */ public class TemplateEntry { // The branch used to generate this entry (if it is associated with a branch). private Branch branch; // The DN for this template entry, if it is known. private DN dn; // The DN of the parent entry for this template entry, if it is available. private DN parentDN; // The set of attributes associated with this template entry, mapped from the // lowercase name of the attribute to the list of generated values. private LinkedHashMap<AttributeType,ArrayList<TemplateValue>> attributes; // The template used to generate this entry (if it is associated with a // template). private Template template; /** * Creates a new template entry that will be associated with the provided * branch. * * @param branch The branch to use when creating this template entry. */ public TemplateEntry(Branch branch) { this.branch = branch; dn = branch.getBranchDN(); template = null; parentDN = null; attributes = new LinkedHashMap<AttributeType,ArrayList<TemplateValue>>(); } /** * Creates a new template entry that will be associated with the provided * template. * * @param template The template used to generate this entry. * @param parentDN The DN of the parent entry for this template entry. */ public TemplateEntry(Template template, DN parentDN) { this.template = template; this.parentDN = parentDN; dn = null; branch = null; attributes = new LinkedHashMap<AttributeType,ArrayList<TemplateValue>>(); } /** * Retrieves the branch used to generate this entry. * * @return The branch used to generate this entry, or <CODE>null</CODE> if it * is associated with a template instead of a branch. */ public Branch getBranch() { return branch; } /** * Retrieves the template used to generate this entry. * * @return The template used to generate this entry, or <CODE>null</CODE> if * it is associated with a branch instead of a template. */ public Template getTemplate() { return template; } /** * Retrieves the DN of the parent entry for this template entry. * * @return The DN of the parent entry for this template entry, or * <CODE>null</CODE> if there is no parent DN. */ public DN getParentDN() { return parentDN; } /** * Retrieves the DN for this template entry, if it is known. * * @return The DN for this template entry if it is known, or * <CODE>null</CODE> if it cannot yet be determined. */ public DN getDN() { if (dn == null) { RDN rdn; AttributeType[] rdnAttrs = template.getRDNAttributes(); if (rdnAttrs.length == 1) { AttributeType t = rdnAttrs[0]; TemplateValue v = getValue(t); if (v == null) { return null; } AttributeValue value = AttributeValues.create(t, v.getValue().toString()); rdn = new RDN(t, value); } else { String[] names = new String[rdnAttrs.length]; AttributeValue[] values = new AttributeValue[rdnAttrs.length]; for (int i=0; i < rdnAttrs.length; i++) { AttributeType t = rdnAttrs[i]; TemplateValue v = getValue(t); if (v == null) { return null; } names[i] = t.getPrimaryName(); values[i] = AttributeValues.create(t, v.getValue().toString()); } rdn = new RDN(rdnAttrs, names, values); } dn = parentDN.concat(rdn); } return dn; } /** * Indicates whether this entry contains one or more values for the specified * attribute type. * * @param attributeType The attribute type for which to make the * determination. * * @return <CODE>true</CODE> if this entry contains one or more values for * the specified attribute type, or <CODE>false</CODE> if not. */ public boolean hasAttribute(AttributeType attributeType) { return attributes.containsKey(attributeType); } /** * Retrieves the value for the specified attribute, if defined. If the * specified attribute has multiple values, then the first will be returned. * * @param attributeType The attribute type for which to retrieve the value. * * @return The value for the specified attribute, or <CODE>null</CODE> if * there are no values for that attribute type. */ public TemplateValue getValue(AttributeType attributeType) { ArrayList<TemplateValue> valueList = attributes.get(attributeType); if ((valueList == null) || valueList.isEmpty()) { return null; } else { return valueList.get(0); } } /** * Retrieves the set of values for the specified attribute, if defined. * * @param attributeType The attribute type for which to retrieve the set of * values. * * @return The set of values for the specified attribute, or * <CODE>null</CODE> if there are no values for that attribute type. */ public List<TemplateValue> getValues(AttributeType attributeType) { ArrayList<TemplateValue> valueList = attributes.get(attributeType); return valueList; } /** * Adds the provided template value to this entry. * * @param value The value to add to this entry. */ public void addValue(TemplateValue value) { ArrayList<TemplateValue> valueList = attributes.get(value.getAttributeType()); if (valueList == null) { valueList = new ArrayList<TemplateValue>(); valueList.add(value); attributes.put(value.getAttributeType(), valueList); } else { valueList.add(value); } } /** * Writes this entry in LDIF form. No filtering will be * performed for this entry, nor will any export plugins be invoked. * * @param exportConfig The configuration that specifies how the * entry should be written. * * @return <CODE>true</CODE> if the entry is actually written, or * <CODE>false</CODE> if it is not for some reason. * * @throws IOException If a problem occurs while writing the * information. * * @throws LDIFException If a problem occurs while trying to * determine whether to write the entry. */ public boolean toLDIF(LDIFExportConfig exportConfig) throws IOException, LDIFException { // Process all of the attributes for this entry. LinkedHashMap<ObjectClass,String> objectClasses = new LinkedHashMap<ObjectClass,String>(); LinkedHashMap<AttributeType,List<Attribute>> userAttributes = new LinkedHashMap<AttributeType,List<Attribute>>(); LinkedHashMap<AttributeType,List<Attribute>> operationalAttributes = new LinkedHashMap<AttributeType,List<Attribute>>(); LinkedHashMap<AttributeType, List<Attribute>> urlAttributes = new LinkedHashMap<AttributeType, List<Attribute>>(); LinkedHashMap<AttributeType, List<Attribute>> base64Attributes = new LinkedHashMap<AttributeType, List<Attribute>>(); for (AttributeType t : attributes.keySet()) { ArrayList<TemplateValue> valueList = attributes.get(t); if (t.isObjectClassType()) { for (TemplateValue v : valueList) { String ocName = toLowerCase(v.getValue().toString()); ObjectClass oc = DirectoryServer.getObjectClass(ocName, true); objectClasses.put(oc, ocName); } } else if (t.isOperational()) { AttributeBuilder builder = new AttributeBuilder(t, t.getNameOrOID()); for (TemplateValue v : valueList) { builder.add(AttributeValues.create(t, v.getValue().toString())); } ArrayList<Attribute> attrList = new ArrayList<Attribute>(1); attrList.add(builder.toAttribute()); operationalAttributes.put(t, attrList); } else { AttributeBuilder builder = new AttributeBuilder(t, t.getNameOrOID()); AttributeBuilder urlBuilder = null; AttributeBuilder base64Builder = null; for (TemplateValue v : valueList) { AttributeValue value = AttributeValues.create(t, v.getValue().toString()); builder.add(value); if (v.getTemplateLine().isURL()) { if (urlBuilder == null) { urlBuilder = new AttributeBuilder(t, t.getNameOrOID()); } urlBuilder.add(value); } else if (v.getTemplateLine().isBase64()) { if (base64Builder == null) { base64Builder = new AttributeBuilder(t, t.getNameOrOID()); } base64Builder.add(value); } } ArrayList<Attribute> attrList = new ArrayList<Attribute>(1); attrList.add(builder.toAttribute()); userAttributes.put(t, attrList); if (urlBuilder != null) { ArrayList<Attribute> urlAttrList = new ArrayList<Attribute>(1); urlAttrList.add(urlBuilder.toAttribute()); urlAttributes.put(t, urlAttrList); } if (base64Builder != null) { ArrayList<Attribute> base64AttrList = new ArrayList<Attribute>(1); base64AttrList.add(base64Builder.toAttribute()); base64Attributes.put(t, base64AttrList); } } } // Get the information necessary to write the LDIF. BufferedWriter writer = exportConfig.getWriter(); int wrapColumn = exportConfig.getWrapColumn(); boolean wrapLines = (wrapColumn > 1); // First, write the DN. It will always be included. StringBuilder dnLine = new StringBuilder(); dnLine.append("dn"); appendLDIFSeparatorAndValue(dnLine, ByteString.valueOf(getDN().toString())); writeLDIFLine(dnLine, writer, wrapLines, wrapColumn); // Next, the set of objectclasses. final boolean typesOnly = exportConfig.typesOnly(); if (exportConfig.includeObjectClasses()) { if (typesOnly) { StringBuilder ocLine = new StringBuilder("objectClass:"); writeLDIFLine(ocLine, writer, wrapLines, wrapColumn); } else { for (String s : objectClasses.values()) { StringBuilder ocLine = new StringBuilder(); ocLine.append("objectClass: "); ocLine.append(s); writeLDIFLine(ocLine, writer, wrapLines, wrapColumn); } } } // Now the set of user attributes. for (AttributeType attrType : userAttributes.keySet()) { if (exportConfig.includeAttribute(attrType)) { List<Attribute> attrList = userAttributes.get(attrType); for (Attribute a : attrList) { if (a.isVirtual() && (! exportConfig.includeVirtualAttributes())) { continue; } if (typesOnly) { StringBuilder attrName = new StringBuilder(a.getName()); for (String o : a.getOptions()) { attrName.append(";"); attrName.append(o); } attrName.append(":"); writeLDIFLine(attrName, writer, wrapLines, wrapColumn); } else { StringBuilder attrName = new StringBuilder(a.getName()); for (String o : a.getOptions()) { attrName.append(";"); attrName.append(o); } List<Attribute> urlAttrList = urlAttributes.get(attrType); List<Attribute> base64AttrList = base64Attributes.get(attrType); for (AttributeValue v : a) { StringBuilder attrLine = new StringBuilder(); attrLine.append(attrName); boolean isURLValue = false; if (urlAttrList != null) { for (Attribute urlAttr : urlAttrList) { for (AttributeValue urlValue : urlAttr) { if (urlValue.equals(v)) { isURLValue = true; break; } } if (isURLValue) { break; } } } boolean isBase64Value = false; if (base64AttrList != null) { for (Attribute base64Attr : base64AttrList) { for (AttributeValue base64Value : base64Attr) { if (base64Value.equals(v)) { isBase64Value = true; break; } } if (isBase64Value) { break; } } } appendLDIFSeparatorAndValue(attrLine, v.getValue(), isURLValue, isBase64Value); writeLDIFLine(attrLine, writer, wrapLines, wrapColumn); } } } } } // Next, the set of operational attributes. if (exportConfig.includeOperationalAttributes()) { for (AttributeType attrType : operationalAttributes.keySet()) { if (exportConfig.includeAttribute(attrType)) { List<Attribute> attrList = operationalAttributes.get(attrType); for (Attribute a : attrList) { if (a.isVirtual() && (! exportConfig.includeVirtualAttributes())) { continue; } if (typesOnly) { StringBuilder attrName = new StringBuilder(a.getName()); for (String o : a.getOptions()) { attrName.append(";"); attrName.append(o); } attrName.append(":"); writeLDIFLine(attrName, writer, wrapLines, wrapColumn); } else { StringBuilder attrName = new StringBuilder(a.getName()); for (String o : a.getOptions()) { attrName.append(";"); attrName.append(o); } for (AttributeValue v : a) { StringBuilder attrLine = new StringBuilder(); attrLine.append(attrName); appendLDIFSeparatorAndValue(attrLine, v.getValue()); writeLDIFLine(attrLine, writer, wrapLines, wrapColumn); } } } } } } // Make sure there is a blank line after the entry. writer.newLine(); return true; } }