/*
|
* 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 legal-notices/CDDLv1_0.txt
|
* or http://forgerock.org/license/CDDLv1.0.html.
|
* 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 legal-notices/CDDLv1_0.txt.
|
* 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.
|
* Portions Copyright 2013-2014 ForgeRock AS.
|
*/
|
package org.opends.server.tools.makeldif;
|
import org.forgerock.i18n.LocalizableMessage;
|
|
|
|
import java.io.BufferedReader;
|
import java.io.File;
|
import java.io.FileReader;
|
import java.io.InputStream;
|
import java.io.InputStreamReader;
|
import java.io.IOException;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Random;
|
import java.util.StringTokenizer;
|
|
import org.opends.server.core.DirectoryServer;
|
import org.opends.server.types.AttributeType;
|
import org.opends.server.types.DN;
|
import org.opends.server.types.InitializationException;
|
|
import static org.opends.messages.ToolMessages.*;
|
|
import static org.opends.server.util.StaticUtils.*;
|
|
|
|
/**
|
* This class defines a template file, which is a collection of constant
|
* definitions, branches, and templates.
|
*/
|
public class TemplateFile
|
{
|
/**
|
* The name of the file holding the list of first names.
|
*/
|
public static final String FIRST_NAME_FILE = "first.names";
|
|
|
|
/**
|
* The name of the file holding the list of last names.
|
*/
|
public static final String LAST_NAME_FILE = "last.names";
|
|
|
|
// A map of the contents of various text files used during the parsing
|
// process, mapped from absolute path to the array of lines in the file.
|
private HashMap<String,String[]> fileLines;
|
|
// The index of the next first name value that should be used.
|
private int firstNameIndex;
|
|
// The index of the next last name value that should be used.
|
private int lastNameIndex;
|
|
// A counter used to keep track of the number of times that the larger of the
|
// first/last name list has been completed.
|
private int nameLoopCounter;
|
|
// A counter that will be used in case we have exhausted all possible first
|
// and last name combinations.
|
private int nameUniquenessCounter;
|
|
// The set of branch definitions for this template file.
|
private LinkedHashMap<DN,Branch> branches;
|
|
// The set of constant definitions for this template file.
|
private LinkedHashMap<String,String> constants;
|
|
// The set of registered tags for this template file.
|
private LinkedHashMap<String,Tag> registeredTags;
|
|
// The set of template definitions for this template file.
|
private LinkedHashMap<String,Template> templates;
|
|
// The random number generator for this template file.
|
private Random random;
|
|
// The next first name that should be used.
|
private String firstName;
|
|
// The next last name that should be used.
|
private String lastName;
|
|
// The resource path to use for filesystem elements that cannot be found
|
// anywhere else.
|
private String resourcePath;
|
|
// The path to the directory containing the template file, if available.
|
private String templatePath;
|
|
// The set of first names to use when generating the LDIF.
|
private String[] firstNames;
|
|
// The set of last names to use when generating the LDIF.
|
private String[] lastNames;
|
|
|
|
/**
|
* Creates a new, empty template file structure.
|
*
|
* @param resourcePath The path to the directory that may contain additional
|
* resource files needed during the LDIF generation
|
* process.
|
*/
|
public TemplateFile(String resourcePath)
|
{
|
this(resourcePath, new Random());
|
}
|
|
|
|
/**
|
* Creates a new, empty template file structure.
|
*
|
*
|
* @param resourcePath The path to the directory that may contain additional
|
* resource files needed during the LDIF generation
|
* process.
|
* @param random The random number generator for this template file.
|
*/
|
public TemplateFile(String resourcePath, Random random)
|
{
|
this.resourcePath = resourcePath;
|
this.random = random;
|
|
fileLines = new HashMap<String,String[]>();
|
branches = new LinkedHashMap<DN,Branch>();
|
constants = new LinkedHashMap<String,String>();
|
registeredTags = new LinkedHashMap<String,Tag>();
|
templates = new LinkedHashMap<String,Template>();
|
templatePath = null;
|
firstNames = new String[0];
|
lastNames = new String[0];
|
firstName = null;
|
lastName = null;
|
firstNameIndex = 0;
|
lastNameIndex = 0;
|
nameLoopCounter = 0;
|
nameUniquenessCounter = 1;
|
|
registerDefaultTags();
|
|
try
|
{
|
readNameFiles();
|
}
|
catch (IOException ioe)
|
{
|
// FIXME -- What to do here?
|
ioe.printStackTrace();
|
firstNames = new String[] { "John" };
|
lastNames = new String[] { "Doe" };
|
}
|
}
|
|
|
|
/**
|
* Retrieves the set of tags that have been registered. They will be in the
|
* form of a mapping between the name of the tag (in all lowercase characters)
|
* and the corresponding tag implementation.
|
*
|
* @return The set of tags that have been registered.
|
*/
|
public Map<String,Tag> getTags()
|
{
|
return registeredTags;
|
}
|
|
|
|
/**
|
* Retrieves the tag with the specified name.
|
*
|
* @param lowerName The name of the tag to retrieve, in all lowercase
|
* characters.
|
*
|
* @return The requested tag, or <CODE>null</CODE> if no such tag has been
|
* registered.
|
*/
|
public Tag getTag(String lowerName)
|
{
|
return registeredTags.get(lowerName);
|
}
|
|
|
|
/**
|
* Registers the specified class as a tag that may be used in templates.
|
*
|
* @param tagClass The fully-qualified name of the class to register as a
|
* tag.
|
*
|
* @throws MakeLDIFException If a problem occurs while attempting to
|
* register the specified tag.
|
*/
|
public void registerTag(String tagClass)
|
throws MakeLDIFException
|
{
|
Class c;
|
try
|
{
|
c = Class.forName(tagClass);
|
}
|
catch (Exception e)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_CANNOT_LOAD_TAG_CLASS.get(tagClass);
|
throw new MakeLDIFException(message, e);
|
}
|
|
Tag t;
|
try
|
{
|
t = (Tag) c.newInstance();
|
}
|
catch (Exception e)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_CANNOT_INSTANTIATE_TAG.get(tagClass);
|
throw new MakeLDIFException(message, e);
|
}
|
|
String lowerName = toLowerCase(t.getName());
|
if (registeredTags.containsKey(lowerName))
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_CONFLICTING_TAG_NAME.get(tagClass, t.getName());
|
throw new MakeLDIFException(message);
|
}
|
else
|
{
|
registeredTags.put(lowerName, t);
|
}
|
}
|
|
|
|
/**
|
* Registers the set of tags that will always be available for use in
|
* templates.
|
*/
|
private void registerDefaultTags()
|
{
|
Class[] defaultTagClasses = new Class[]
|
{
|
AttributeValueTag.class,
|
DNTag.class,
|
FileTag.class,
|
FirstNameTag.class,
|
GUIDTag.class,
|
IfAbsentTag.class,
|
IfPresentTag.class,
|
LastNameTag.class,
|
ListTag.class,
|
ParentDNTag.class,
|
PresenceTag.class,
|
RandomTag.class,
|
RDNTag.class,
|
SequentialTag.class,
|
StaticTextTag.class,
|
UnderscoreDNTag.class,
|
UnderscoreParentDNTag.class
|
};
|
|
for (Class c : defaultTagClasses)
|
{
|
try
|
{
|
Tag t = (Tag) c.newInstance();
|
registeredTags.put(toLowerCase(t.getName()), t);
|
}
|
catch (Exception e)
|
{
|
// This should never happen.
|
e.printStackTrace();
|
}
|
}
|
}
|
|
|
|
/**
|
* Retrieves the set of constants defined for this template file.
|
*
|
* @return The set of constants defined for this template file.
|
*/
|
public Map<String,String> getConstants()
|
{
|
return constants;
|
}
|
|
|
|
/**
|
* Retrieves the value of the constant with the specified name.
|
*
|
* @param lowerName The name of the constant to retrieve, in all lowercase
|
* characters.
|
*
|
* @return The value of the constant with the specified name, or
|
* <CODE>null</CODE> if there is no such constant.
|
*/
|
public String getConstant(String lowerName)
|
{
|
return constants.get(lowerName);
|
}
|
|
|
|
/**
|
* Registers the provided constant for use in the template.
|
*
|
* @param name The name for the constant.
|
* @param value The value for the constant.
|
*/
|
public void registerConstant(String name, String value)
|
{
|
constants.put(toLowerCase(name), value);
|
}
|
|
|
|
/**
|
* Retrieves the set of branches defined in this template file.
|
*
|
* @return The set of branches defined in this template file.
|
*/
|
public Map<DN,Branch> getBranches()
|
{
|
return branches;
|
}
|
|
|
|
/**
|
* Retrieves the branch registered with the specified DN.
|
*
|
* @param branchDN The DN for which to retrieve the corresponding branch.
|
*
|
* @return The requested branch, or <CODE>null</CODE> if no such branch has
|
* been registered.
|
*/
|
public Branch getBranch(DN branchDN)
|
{
|
return branches.get(branchDN);
|
}
|
|
|
|
/**
|
* Registers the provided branch in this template file.
|
*
|
* @param branch The branch to be registered.
|
*/
|
public void registerBranch(Branch branch)
|
{
|
branches.put(branch.getBranchDN(), branch);
|
}
|
|
|
|
/**
|
* Retrieves the set of templates defined in this template file.
|
*
|
* @return The set of templates defined in this template file.
|
*/
|
public Map<String,Template> getTemplates()
|
{
|
return templates;
|
}
|
|
|
|
/**
|
* Retrieves the template with the specified name.
|
*
|
* @param lowerName The name of the template to retrieve, in all lowercase
|
* characters.
|
*
|
* @return The requested template, or <CODE>null</CODE> if there is no such
|
* template.
|
*/
|
public Template getTemplate(String lowerName)
|
{
|
return templates.get(lowerName);
|
}
|
|
|
|
/**
|
* Registers the provided template for use in this template file.
|
*
|
* @param template The template to be registered.
|
*/
|
public void registerTemplate(Template template)
|
{
|
templates.put(toLowerCase(template.getName()), template);
|
}
|
|
|
|
/**
|
* Retrieves the random number generator for this template file.
|
*
|
* @return The random number generator for this template file.
|
*/
|
public Random getRandom()
|
{
|
return random;
|
}
|
|
|
|
/**
|
* Reads the contents of the first and last name files into the appropriate
|
* arrays and sets up the associated index pointers.
|
*
|
* @throws IOException If a problem occurs while reading either of the
|
* files.
|
*/
|
private void readNameFiles()
|
throws IOException
|
{
|
File f = getFile(FIRST_NAME_FILE);
|
ArrayList<String> nameList = new ArrayList<String>();
|
BufferedReader reader = new BufferedReader(new FileReader(f));
|
while (true)
|
{
|
String line = reader.readLine();
|
if (line == null)
|
{
|
break;
|
}
|
else
|
{
|
nameList.add(line);
|
}
|
}
|
reader.close();
|
firstNames = new String[nameList.size()];
|
nameList.toArray(firstNames);
|
|
f = getFile(LAST_NAME_FILE);
|
nameList = new ArrayList<String>();
|
reader = new BufferedReader(new FileReader(f));
|
while (true)
|
{
|
String line = reader.readLine();
|
if (line == null)
|
{
|
break;
|
}
|
else
|
{
|
nameList.add(line);
|
}
|
}
|
reader.close();
|
lastNames = new String[nameList.size()];
|
nameList.toArray(lastNames);
|
}
|
|
|
|
/**
|
* Updates the first and last name indexes to choose new values. The
|
* algorithm used is designed to ensure that the combination of first and last
|
* names will never be repeated. It depends on the number of first names and
|
* the number of last names being relatively prime. This method should be
|
* called before beginning generation of each template entry.
|
*/
|
public void nextFirstAndLastNames()
|
{
|
firstName = firstNames[firstNameIndex++];
|
lastName = lastNames[lastNameIndex++];
|
|
|
// If we've already exhausted every possible combination, then append an
|
// integer to the last name.
|
if (nameUniquenessCounter > 1)
|
{
|
lastName += nameUniquenessCounter;
|
}
|
|
if (firstNameIndex >= firstNames.length)
|
{
|
// We're at the end of the first name list, so start over. If the first
|
// name list is larger than the last name list, then we'll also need to
|
// set the last name index to the next loop counter position.
|
firstNameIndex = 0;
|
if (firstNames.length > lastNames.length)
|
{
|
lastNameIndex = ++nameLoopCounter;
|
if (lastNameIndex >= lastNames.length)
|
{
|
lastNameIndex = 0;
|
nameUniquenessCounter++;
|
}
|
}
|
}
|
|
if (lastNameIndex >= lastNames.length)
|
{
|
// We're at the end of the last name list, so start over. If the last
|
// name list is larger than the first name list, then we'll also need to
|
// set the first name index to the next loop counter position.
|
lastNameIndex = 0;
|
if (lastNames.length > firstNames.length)
|
{
|
firstNameIndex = ++nameLoopCounter;
|
if (firstNameIndex >= firstNames.length)
|
{
|
firstNameIndex = 0;
|
nameUniquenessCounter++;
|
}
|
}
|
}
|
}
|
|
|
|
/**
|
* Retrieves the first name value that should be used for the current entry.
|
*
|
* @return The first name value that should be used for the current entry.
|
*/
|
public String getFirstName()
|
{
|
return firstName;
|
}
|
|
|
|
/**
|
* Retrieves the last name value that should be used for the current entry.
|
*
|
* @return The last name value that should be used for the current entry.
|
*/
|
public String getLastName()
|
{
|
return lastName;
|
}
|
|
|
|
/**
|
* Parses the contents of the specified file as a MakeLDIF template file
|
* definition.
|
*
|
* @param filename The name of the file containing the template data.
|
* @param warnings A list into which any warnings identified may be placed.
|
*
|
* @throws IOException If a problem occurs while attempting to read data
|
* from the specified file.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* any of the MakeLDIF components.
|
*
|
* @throws MakeLDIFException If any other problem occurs while parsing the
|
* template file.
|
*/
|
public void parse(String filename, List<LocalizableMessage> warnings)
|
throws IOException, InitializationException, MakeLDIFException
|
{
|
ArrayList<String> fileLines = new ArrayList<String>();
|
|
templatePath = null;
|
File f = getFile(filename);
|
if ((f == null) || (! f.exists()))
|
{
|
LocalizableMessage message = ERR_MAKELDIF_COULD_NOT_FIND_TEMPLATE_FILE.get(filename);
|
throw new IOException(message.toString());
|
}
|
else
|
{
|
templatePath = f.getParentFile().getAbsolutePath();
|
}
|
|
BufferedReader reader = new BufferedReader(new FileReader(f));
|
while (true)
|
{
|
String line = reader.readLine();
|
if (line == null)
|
{
|
break;
|
}
|
else
|
{
|
fileLines.add(line);
|
}
|
}
|
|
reader.close();
|
|
String[] lines = new String[fileLines.size()];
|
fileLines.toArray(lines);
|
parse(lines, warnings);
|
}
|
|
|
|
/**
|
* Parses the data read from the provided input stream as a MakeLDIF template
|
* file definition.
|
*
|
* @param inputStream The input stream from which to read the template file
|
* data.
|
* @param warnings A list into which any warnings identified may be
|
* placed.
|
*
|
* @throws IOException If a problem occurs while attempting to read data
|
* from the provided input stream.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* any of the MakeLDIF components.
|
*
|
* @throws MakeLDIFException If any other problem occurs while parsing the
|
* template file.
|
*/
|
public void parse(InputStream inputStream, List<LocalizableMessage> warnings)
|
throws IOException, InitializationException, MakeLDIFException
|
{
|
ArrayList<String> fileLines = new ArrayList<String>();
|
|
BufferedReader reader =
|
new BufferedReader(new InputStreamReader(inputStream));
|
while (true)
|
{
|
String line = reader.readLine();
|
if (line == null)
|
{
|
break;
|
}
|
else
|
{
|
fileLines.add(line);
|
}
|
}
|
|
reader.close();
|
|
String[] lines = new String[fileLines.size()];
|
fileLines.toArray(lines);
|
parse(lines, warnings);
|
}
|
|
|
|
/**
|
* Parses the provided data as a MakeLDIF template file definition.
|
*
|
* @param lines The lines that make up the template file.
|
* @param warnings A list into which any warnings identified may be placed.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* any of the MakeLDIF components.
|
*
|
* @throws MakeLDIFException If any other problem occurs while parsing the
|
* template file.
|
*/
|
public void parse(String[] lines, List<LocalizableMessage> warnings)
|
throws InitializationException, MakeLDIFException
|
{
|
// Create temporary variables that will be used to hold the data read.
|
LinkedHashMap<String,Tag> templateFileIncludeTags =
|
new LinkedHashMap<String,Tag>();
|
LinkedHashMap<String,String> templateFileConstants =
|
new LinkedHashMap<String,String>();
|
LinkedHashMap<DN,Branch> templateFileBranches =
|
new LinkedHashMap<DN,Branch>();
|
LinkedHashMap<String,Template> templateFileTemplates =
|
new LinkedHashMap<String,Template>();
|
|
for (int lineNumber=0; lineNumber < lines.length; lineNumber++)
|
{
|
String line = lines[lineNumber];
|
|
line = replaceConstants(line, lineNumber,
|
templateFileConstants, warnings);
|
|
String lowerLine = toLowerCase(line);
|
if ((line.length() == 0) || line.startsWith("#"))
|
{
|
// This is a comment or a blank line, so we'll ignore it.
|
continue;
|
}
|
else if (lowerLine.startsWith("include "))
|
{
|
// This should be an include definition. The next element should be the
|
// name of the class. Load and instantiate it and make sure there are
|
// no conflicts.
|
String className = line.substring(8).trim();
|
|
Class tagClass;
|
try
|
{
|
tagClass = Class.forName(className);
|
}
|
catch (Exception e)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_CANNOT_LOAD_TAG_CLASS.get(className);
|
throw new MakeLDIFException(message, e);
|
}
|
|
Tag tag;
|
try
|
{
|
tag = (Tag) tagClass.newInstance();
|
}
|
catch (Exception e)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_CANNOT_INSTANTIATE_TAG.get(className);
|
throw new MakeLDIFException(message, e);
|
}
|
|
String lowerName = toLowerCase(tag.getName());
|
if (registeredTags.containsKey(lowerName) ||
|
templateFileIncludeTags.containsKey(lowerName))
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_CONFLICTING_TAG_NAME.get(className, tag.getName());
|
throw new MakeLDIFException(message);
|
}
|
|
templateFileIncludeTags.put(lowerName, tag);
|
}
|
else if (lowerLine.startsWith("define "))
|
{
|
// This should be a constant definition. The rest of the line should
|
// contain the constant name, an equal sign, and the constant value.
|
int equalPos = line.indexOf('=', 7);
|
if (equalPos < 0)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_DEFINE_MISSING_EQUALS.get(lineNumber);
|
throw new MakeLDIFException(message);
|
}
|
|
String name = line.substring(7, equalPos).trim();
|
if (name.length() == 0)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_DEFINE_NAME_EMPTY.get(lineNumber);
|
throw new MakeLDIFException(message);
|
}
|
|
String lowerName = toLowerCase(name);
|
if (templateFileConstants.containsKey(lowerName))
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_CONFLICTING_CONSTANT_NAME.get(name, lineNumber);
|
throw new MakeLDIFException(message);
|
}
|
|
String value = line.substring(equalPos+1);
|
if (value.length() == 0)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_WARNING_DEFINE_VALUE_EMPTY.get(
|
name, lineNumber);
|
warnings.add(message);
|
}
|
|
templateFileConstants.put(lowerName, value);
|
}
|
else if (lowerLine.startsWith("branch: "))
|
{
|
int startLineNumber = lineNumber;
|
ArrayList<String> lineList = new ArrayList<String>();
|
lineList.add(line);
|
while (true)
|
{
|
lineNumber++;
|
if (lineNumber >= lines.length)
|
{
|
break;
|
}
|
|
line = lines[lineNumber];
|
if (line.length() == 0)
|
{
|
break;
|
}
|
else
|
{
|
line = replaceConstants(line, lineNumber,
|
templateFileConstants, warnings);
|
lineList.add(line);
|
}
|
}
|
|
String[] branchLines = new String[lineList.size()];
|
lineList.toArray(branchLines);
|
|
Branch b = parseBranchDefinition(branchLines, lineNumber,
|
templateFileIncludeTags,
|
warnings);
|
DN branchDN = b.getBranchDN();
|
if (templateFileBranches.containsKey(branchDN))
|
{
|
LocalizableMessage message = ERR_MAKELDIF_CONFLICTING_BRANCH_DN.get(
|
String.valueOf(branchDN), startLineNumber);
|
throw new MakeLDIFException(message);
|
}
|
else
|
{
|
templateFileBranches.put(branchDN, b);
|
}
|
}
|
else if (lowerLine.startsWith("template: "))
|
{
|
int startLineNumber = lineNumber;
|
ArrayList<String> lineList = new ArrayList<String>();
|
lineList.add(line);
|
while (true)
|
{
|
lineNumber++;
|
if (lineNumber >= lines.length)
|
{
|
break;
|
}
|
|
line = lines[lineNumber];
|
if (line.length() == 0)
|
{
|
break;
|
}
|
else
|
{
|
line = replaceConstants(line, lineNumber,
|
templateFileConstants, warnings);
|
lineList.add(line);
|
}
|
}
|
|
String[] templateLines = new String[lineList.size()];
|
lineList.toArray(templateLines);
|
|
Template t = parseTemplateDefinition(templateLines, startLineNumber,
|
templateFileIncludeTags,
|
templateFileTemplates, warnings);
|
String lowerName = toLowerCase(t.getName());
|
if (templateFileTemplates.containsKey(lowerName))
|
{
|
LocalizableMessage message = ERR_MAKELDIF_CONFLICTING_TEMPLATE_NAME.get(
|
String.valueOf(t.getName()), startLineNumber);
|
throw new MakeLDIFException(message);
|
}
|
else
|
{
|
templateFileTemplates.put(lowerName, t);
|
}
|
}
|
else
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_UNEXPECTED_TEMPLATE_FILE_LINE.get(line, lineNumber);
|
throw new MakeLDIFException(message);
|
}
|
}
|
|
|
// If we've gotten here, then we're almost done. We just need to finalize
|
// the branch and template definitions and then update the template file
|
// variables.
|
for (Branch b : templateFileBranches.values())
|
{
|
b.completeBranchInitialization(templateFileTemplates);
|
}
|
|
for (Template t : templateFileTemplates.values())
|
{
|
t.completeTemplateInitialization(templateFileTemplates);
|
}
|
|
registeredTags.putAll(templateFileIncludeTags);
|
constants.putAll(templateFileConstants);
|
branches.putAll(templateFileBranches);
|
templates.putAll(templateFileTemplates);
|
}
|
|
|
/**
|
* Parse a line and replace all constants within [ ] with their
|
* values.
|
*
|
* @param line The line to parse.
|
* @param lineNumber The line number in the template file.
|
* @param constants The set of constants defined in the template file.
|
* @param warnings A list into which any warnings identified may be
|
* placed.
|
* @return The line in which all constant variables have been replaced
|
* with their value
|
*/
|
private String replaceConstants(String line, int lineNumber,
|
Map<String,String> constants,
|
List<LocalizableMessage> warnings)
|
{
|
int closePos = line.lastIndexOf(']');
|
// Loop until we've scanned all closing brackets
|
do
|
{
|
// Skip escaped closing brackets
|
while (closePos > 0 &&
|
line.charAt(closePos - 1) == '\\')
|
{
|
closePos = line.lastIndexOf(']', closePos - 1);
|
}
|
if (closePos > 0)
|
{
|
StringBuilder lineBuffer = new StringBuilder(line);
|
int openPos = line.lastIndexOf('[', closePos);
|
// Find the opening bracket. If it's escaped, then it's not a constant
|
if ((openPos > 0 && line.charAt(openPos - 1) != '\\') ||
|
(openPos == 0))
|
{
|
String constantName =
|
toLowerCase(line.substring(openPos+1, closePos));
|
String constantValue = constants.get(constantName);
|
if (constantValue == null)
|
{
|
LocalizableMessage message = WARN_MAKELDIF_WARNING_UNDEFINED_CONSTANT.get(
|
constantName, lineNumber);
|
warnings.add(message);
|
}
|
else
|
{
|
lineBuffer.replace(openPos, closePos+1, constantValue);
|
}
|
}
|
if (openPos >= 0)
|
{
|
closePos = openPos;
|
}
|
line = lineBuffer.toString();
|
closePos = line.lastIndexOf(']', closePos);
|
}
|
} while (closePos > 0);
|
return line;
|
}
|
|
/**
|
* Parses the information contained in the provided set of lines as a MakeLDIF
|
* branch definition.
|
*
|
*
|
* @param branchLines The set of lines containing the branch definition.
|
* @param startLineNumber The line number in the template file on which the
|
* first of the branch lines appears.
|
* @param tags The set of defined tags from the template file.
|
* Note that this does not include the tags that are
|
* always registered by default.
|
* @param warnings A list into which any warnings identified may be
|
* placed.
|
*
|
* @return The decoded branch definition.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* any of the branch elements.
|
*
|
* @throws MakeLDIFException If some other problem occurs during processing.
|
*/
|
private Branch parseBranchDefinition(String[] branchLines,
|
int startLineNumber,
|
Map<String, Tag> tags,
|
List<LocalizableMessage> warnings)
|
throws InitializationException, MakeLDIFException
|
{
|
// The first line must be "branch: " followed by the branch DN.
|
String dnString = branchLines[0].substring(8).trim();
|
DN branchDN;
|
try
|
{
|
branchDN = DN.valueOf(dnString);
|
}
|
catch (Exception e)
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_CANNOT_DECODE_BRANCH_DN.get(dnString, startLineNumber);
|
throw new MakeLDIFException(message);
|
}
|
|
|
// Create a new branch that will be used for the verification process.
|
Branch branch = new Branch(this, branchDN);
|
|
for (int i=1; i < branchLines.length; i++)
|
{
|
String line = branchLines[i];
|
String lowerLine = toLowerCase(line);
|
int lineNumber = startLineNumber + i;
|
|
if (lowerLine.startsWith("#"))
|
{
|
// It's a comment, so we should ignore it.
|
continue;
|
}
|
else if (lowerLine.startsWith("subordinatetemplate: "))
|
{
|
// It's a subordinate template, so we'll want to parse the name and the
|
// number of entries.
|
int colonPos = line.indexOf(':', 21);
|
if (colonPos <= 21)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_BRANCH_SUBORDINATE_TEMPLATE_NO_COLON.
|
get(lineNumber, dnString);
|
throw new MakeLDIFException(message);
|
}
|
|
String templateName = line.substring(21, colonPos).trim();
|
|
int numEntries;
|
try
|
{
|
numEntries = Integer.parseInt(line.substring(colonPos+1).trim());
|
if (numEntries < 0)
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_BRANCH_SUBORDINATE_INVALID_NUM_ENTRIES.
|
get(lineNumber, dnString, numEntries, templateName);
|
throw new MakeLDIFException(message);
|
}
|
else if (numEntries == 0)
|
{
|
LocalizableMessage message = WARN_MAKELDIF_BRANCH_SUBORDINATE_ZERO_ENTRIES.get(
|
lineNumber, dnString,
|
templateName);
|
warnings.add(message);
|
}
|
|
branch.addSubordinateTemplate(templateName, numEntries);
|
}
|
catch (NumberFormatException nfe)
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_BRANCH_SUBORDINATE_CANT_PARSE_NUMENTRIES.
|
get(templateName, lineNumber, dnString);
|
throw new MakeLDIFException(message);
|
}
|
}
|
else
|
{
|
TemplateLine templateLine = parseTemplateLine(line, lowerLine,
|
lineNumber, branch, null,
|
tags, warnings);
|
branch.addExtraLine(templateLine);
|
}
|
}
|
|
return branch;
|
}
|
|
|
|
/**
|
* Parses the information contained in the provided set of lines as a MakeLDIF
|
* template definition.
|
*
|
*
|
* @param templateLines The set of lines containing the template
|
* definition.
|
* @param startLineNumber The line number in the template file on which the
|
* first of the template lines appears.
|
* @param tags The set of defined tags from the template file.
|
* Note that this does not include the tags that are
|
* always registered by default.
|
* @param definedTemplates The set of templates already defined in the
|
* template file.
|
* @param warnings A list into which any warnings identified may be
|
* placed.
|
*
|
* @return The decoded template definition.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* any of the template elements.
|
*
|
* @throws MakeLDIFException If some other problem occurs during processing.
|
*/
|
private Template parseTemplateDefinition(String[] templateLines,
|
int startLineNumber,
|
Map<String, Tag> tags,
|
Map<String, Template>
|
definedTemplates,
|
List<LocalizableMessage> warnings)
|
throws InitializationException, MakeLDIFException
|
{
|
// The first line must be "template: " followed by the template name.
|
String templateName = templateLines[0].substring(10).trim();
|
|
|
// The next line may start with either "extends: ", "rdnAttr: ", or
|
// "subordinateTemplate: ". Keep reading until we find something that's
|
// not one of those.
|
int arrayLineNumber = 1;
|
Template parentTemplate = null;
|
AttributeType[] rdnAttributes = null;
|
ArrayList<String> subTemplateNames = new ArrayList<String>();
|
ArrayList<Integer> entriesPerTemplate = new ArrayList<Integer>();
|
for ( ; arrayLineNumber < templateLines.length; arrayLineNumber++)
|
{
|
int lineNumber = startLineNumber + arrayLineNumber;
|
String line = templateLines[arrayLineNumber];
|
String lowerLine = toLowerCase(line);
|
|
if (lowerLine.startsWith("#"))
|
{
|
// It's a comment. Ignore it.
|
continue;
|
}
|
else if (lowerLine.startsWith("extends: "))
|
{
|
String parentTemplateName = line.substring(9).trim();
|
parentTemplate = definedTemplates.get(parentTemplateName.toLowerCase());
|
if (parentTemplate == null)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_TEMPLATE_INVALID_PARENT_TEMPLATE.get(
|
parentTemplateName, lineNumber, templateName);
|
throw new MakeLDIFException(message);
|
}
|
}
|
else if (lowerLine.startsWith("rdnattr: "))
|
{
|
// This is the set of RDN attributes. If there are multiple, they may
|
// be separated by plus signs.
|
ArrayList<AttributeType> attrList = new ArrayList<AttributeType>();
|
String rdnAttrNames = lowerLine.substring(9).trim();
|
StringTokenizer tokenizer = new StringTokenizer(rdnAttrNames, "+");
|
while (tokenizer.hasMoreTokens())
|
{
|
attrList.add(DirectoryServer.getAttributeType(tokenizer.nextToken(),
|
true));
|
}
|
|
rdnAttributes = new AttributeType[attrList.size()];
|
attrList.toArray(rdnAttributes);
|
}
|
else if (lowerLine.startsWith("subordinatetemplate: "))
|
{
|
// It's a subordinate template, so we'll want to parse the name and the
|
// number of entries.
|
int colonPos = line.indexOf(':', 21);
|
if (colonPos <= 21)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_TEMPLATE_SUBORDINATE_TEMPLATE_NO_COLON.
|
get(lineNumber, templateName);
|
throw new MakeLDIFException(message);
|
}
|
|
String subTemplateName = line.substring(21, colonPos).trim();
|
|
int numEntries;
|
try
|
{
|
numEntries = Integer.parseInt(line.substring(colonPos+1).trim());
|
if (numEntries < 0)
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_TEMPLATE_SUBORDINATE_INVALID_NUM_ENTRIES.
|
get(lineNumber, templateName, numEntries, subTemplateName);
|
throw new MakeLDIFException(message);
|
}
|
else if (numEntries == 0)
|
{
|
LocalizableMessage message = WARN_MAKELDIF_TEMPLATE_SUBORDINATE_ZERO_ENTRIES
|
.get(lineNumber, templateName, subTemplateName);
|
warnings.add(message);
|
}
|
|
subTemplateNames.add(subTemplateName);
|
entriesPerTemplate.add(numEntries);
|
}
|
catch (NumberFormatException nfe)
|
{
|
LocalizableMessage message =
|
ERR_MAKELDIF_TEMPLATE_SUBORDINATE_CANT_PARSE_NUMENTRIES.
|
get(subTemplateName, lineNumber, templateName);
|
throw new MakeLDIFException(message);
|
}
|
}
|
else
|
{
|
// It's something we don't recognize, so it must be a template line.
|
break;
|
}
|
}
|
|
// Create a new template that will be used for the verification process.
|
String[] subordinateTemplateNames = new String[subTemplateNames.size()];
|
subTemplateNames.toArray(subordinateTemplateNames);
|
|
int[] numEntriesPerTemplate = new int[entriesPerTemplate.size()];
|
for (int i=0; i < numEntriesPerTemplate.length; i++)
|
{
|
numEntriesPerTemplate[i] = entriesPerTemplate.get(i);
|
}
|
|
TemplateLine[] parsedLines;
|
if (parentTemplate == null)
|
{
|
parsedLines = new TemplateLine[0];
|
}
|
else
|
{
|
TemplateLine[] parentLines = parentTemplate.getTemplateLines();
|
parsedLines = new TemplateLine[parentLines.length];
|
System.arraycopy(parentLines, 0, parsedLines, 0, parentLines.length);
|
}
|
|
Template template = new Template(this, templateName, rdnAttributes,
|
subordinateTemplateNames,
|
numEntriesPerTemplate, parsedLines);
|
|
for ( ; arrayLineNumber < templateLines.length; arrayLineNumber++)
|
{
|
String line = templateLines[arrayLineNumber];
|
String lowerLine = toLowerCase(line);
|
int lineNumber = startLineNumber + arrayLineNumber;
|
|
if (lowerLine.startsWith("#"))
|
{
|
// It's a comment, so we should ignore it.
|
continue;
|
}
|
else
|
{
|
TemplateLine templateLine = parseTemplateLine(line, lowerLine,
|
lineNumber, null,
|
template, tags, warnings);
|
template.addTemplateLine(templateLine);
|
}
|
}
|
|
return template;
|
}
|
|
|
|
/**
|
* Parses the provided line as a template line. Note that exactly one of the
|
* branch or template arguments must be non-null and the other must be null.
|
*
|
* @param line The text of the template line.
|
* @param lowerLine The template line in all lowercase characters.
|
* @param lineNumber The line number on which the template line appears.
|
* @param branch The branch with which the template line is associated.
|
* @param template The template with which the template line is
|
* associated.
|
* @param tags The set of defined tags from the template file. Note
|
* that this does not include the tags that are always
|
* registered by default.
|
* @param warnings A list into which any warnings identified may be
|
* placed.
|
*
|
* @return The template line that has been parsed.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* any of the template elements.
|
*
|
* @throws MakeLDIFException If some other problem occurs during processing.
|
*/
|
private TemplateLine parseTemplateLine(String line, String lowerLine,
|
int lineNumber, Branch branch,
|
Template template,
|
Map<String,Tag> tags,
|
List<LocalizableMessage> warnings)
|
throws InitializationException, MakeLDIFException
|
{
|
// The first component must be the attribute type, followed by a colon.
|
int colonPos = lowerLine.indexOf(':');
|
if (colonPos < 0)
|
{
|
if (branch == null)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_NO_COLON_IN_TEMPLATE_LINE.get(
|
lineNumber, template.getName());
|
throw new MakeLDIFException(message);
|
}
|
else
|
{
|
LocalizableMessage message = ERR_MAKELDIF_NO_COLON_IN_BRANCH_EXTRA_LINE.get(
|
lineNumber, String.valueOf(branch.getBranchDN()));
|
throw new MakeLDIFException(message);
|
}
|
}
|
else if (colonPos == 0)
|
{
|
if (branch == null)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_NO_ATTR_IN_TEMPLATE_LINE.get(
|
lineNumber, template.getName());
|
throw new MakeLDIFException(message);
|
}
|
else
|
{
|
LocalizableMessage message = ERR_MAKELDIF_NO_ATTR_IN_BRANCH_EXTRA_LINE.get(
|
lineNumber, String.valueOf(branch.getBranchDN()));
|
throw new MakeLDIFException(message);
|
}
|
}
|
|
AttributeType attributeType =
|
DirectoryServer.getAttributeType(lowerLine.substring(0, colonPos),
|
true);
|
|
|
// First, check whether the value is an URL value: <attrName>:< <url>
|
int length = line.length();
|
int pos = colonPos + 1;
|
boolean valueIsURL = false;
|
boolean valueIsBase64 = false;
|
if (pos < length)
|
{
|
if (lowerLine.charAt(pos) == '<')
|
{
|
valueIsURL = true;
|
pos ++;
|
}
|
else if (lowerLine.charAt(pos) == ':')
|
{
|
valueIsBase64 = true;
|
pos ++;
|
}
|
}
|
// Then, find the position of the first non-blank character in the line.
|
while ((pos < length) && (lowerLine.charAt(pos) == ' '))
|
{
|
pos++;
|
}
|
|
if (pos >= length)
|
{
|
// We've hit the end of the line with no value. We'll allow it, but add a
|
// warning.
|
if (branch == null)
|
{
|
LocalizableMessage message = WARN_MAKELDIF_NO_VALUE_IN_TEMPLATE_LINE.get(
|
lineNumber, template.getName());
|
warnings.add(message);
|
}
|
else
|
{
|
LocalizableMessage message = WARN_MAKELDIF_NO_VALUE_IN_BRANCH_EXTRA_LINE.get(
|
lineNumber, String.valueOf(branch.getBranchDN()));
|
warnings.add(message);
|
}
|
}
|
|
|
// Define constants that specify what we're currently parsing.
|
final int PARSING_STATIC_TEXT = 0;
|
final int PARSING_REPLACEMENT_TAG = 1;
|
final int PARSING_ATTRIBUTE_TAG = 2;
|
final int PARSING_ESCAPED_CHAR = 3;
|
|
int phase = PARSING_STATIC_TEXT;
|
int previousPhase = PARSING_STATIC_TEXT;
|
|
ArrayList<Tag> tagList = new ArrayList<Tag>();
|
StringBuilder buffer = new StringBuilder();
|
|
for ( ; pos < length; pos++)
|
{
|
char c = line.charAt(pos);
|
switch (phase)
|
{
|
case PARSING_STATIC_TEXT:
|
switch (c)
|
{
|
case '\\':
|
phase = PARSING_ESCAPED_CHAR;
|
previousPhase = PARSING_STATIC_TEXT;
|
break;
|
case '<':
|
if (buffer.length() > 0)
|
{
|
StaticTextTag t = new StaticTextTag();
|
String[] args = new String[] { buffer.toString() };
|
t.initializeForBranch(this, branch, args, lineNumber,
|
warnings);
|
tagList.add(t);
|
buffer = new StringBuilder();
|
}
|
|
phase = PARSING_REPLACEMENT_TAG;
|
break;
|
case '{':
|
if (buffer.length() > 0)
|
{
|
StaticTextTag t = new StaticTextTag();
|
String[] args = new String[] { buffer.toString() };
|
t.initializeForBranch(this, branch, args, lineNumber,
|
warnings);
|
tagList.add(t);
|
buffer = new StringBuilder();
|
}
|
|
phase = PARSING_ATTRIBUTE_TAG;
|
break;
|
default:
|
buffer.append(c);
|
}
|
break;
|
|
case PARSING_REPLACEMENT_TAG:
|
switch (c)
|
{
|
case '\\':
|
phase = PARSING_ESCAPED_CHAR;
|
previousPhase = PARSING_REPLACEMENT_TAG;
|
break;
|
case '>':
|
Tag t = parseReplacementTag(buffer.toString(), branch, template,
|
lineNumber, tags, warnings);
|
tagList.add(t);
|
buffer = new StringBuilder();
|
|
phase = PARSING_STATIC_TEXT;
|
break;
|
default:
|
buffer.append(c);
|
break;
|
}
|
break;
|
|
case PARSING_ATTRIBUTE_TAG:
|
switch (c)
|
{
|
case '\\':
|
phase = PARSING_ESCAPED_CHAR;
|
previousPhase = PARSING_ATTRIBUTE_TAG;
|
break;
|
case '}':
|
Tag t = parseAttributeTag(buffer.toString(), branch, template,
|
lineNumber, warnings);
|
tagList.add(t);
|
buffer = new StringBuilder();
|
|
phase = PARSING_STATIC_TEXT;
|
break;
|
default:
|
buffer.append(c);
|
break;
|
}
|
break;
|
|
case PARSING_ESCAPED_CHAR:
|
buffer.append(c);
|
phase = previousPhase;
|
break;
|
}
|
}
|
|
if (phase == PARSING_STATIC_TEXT)
|
{
|
if (buffer.length() > 0)
|
{
|
StaticTextTag t = new StaticTextTag();
|
String[] args = new String[] { buffer.toString() };
|
t.initializeForBranch(this, branch, args, lineNumber, warnings);
|
tagList.add(t);
|
}
|
}
|
else
|
{
|
LocalizableMessage message = ERR_MAKELDIF_INCOMPLETE_TAG.get(lineNumber);
|
throw new InitializationException(message);
|
}
|
|
Tag[] tagArray = new Tag[tagList.size()];
|
tagList.toArray(tagArray);
|
return new TemplateLine(attributeType, lineNumber, tagArray, valueIsURL,
|
valueIsBase64);
|
}
|
|
|
|
/**
|
* Parses the provided string as a replacement tag. Exactly one of the branch
|
* or template must be null, and the other must be non-null.
|
*
|
* @param tagString The string containing the encoded tag.
|
* @param branch The branch in which this tag appears.
|
* @param template The template in which this tag appears.
|
* @param lineNumber The line number on which this tag appears in the
|
* template file.
|
* @param tags The set of defined tags from the template file. Note
|
* that this does not include the tags that are always
|
* registered by default.
|
* @param warnings A list into which any warnings identified may be
|
* placed.
|
*
|
* @return The replacement tag parsed from the provided string.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* the tag.
|
*
|
* @throws MakeLDIFException If some other problem occurs during processing.
|
*/
|
private Tag parseReplacementTag(String tagString, Branch branch,
|
Template template, int lineNumber,
|
Map<String,Tag> tags,
|
List<LocalizableMessage> warnings)
|
throws InitializationException, MakeLDIFException
|
{
|
// The components of the replacement tag will be separated by colons, with
|
// the first being the tag name and the remainder being arguments.
|
StringTokenizer tokenizer = new StringTokenizer(tagString, ":");
|
String tagName = tokenizer.nextToken().trim();
|
String lowerTagName = toLowerCase(tagName);
|
|
Tag t = getTag(lowerTagName);
|
if (t == null)
|
{
|
t = tags.get(lowerTagName);
|
if (t == null)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_NO_SUCH_TAG.get(tagName, lineNumber);
|
throw new MakeLDIFException(message);
|
}
|
}
|
|
ArrayList<String> argList = new ArrayList<String>();
|
while (tokenizer.hasMoreTokens())
|
{
|
argList.add(tokenizer.nextToken().trim());
|
}
|
|
String[] args = new String[argList.size()];
|
argList.toArray(args);
|
|
|
Tag newTag;
|
try
|
{
|
newTag = t.getClass().newInstance();
|
}
|
catch (Exception e)
|
{
|
LocalizableMessage message = ERR_MAKELDIF_CANNOT_INSTANTIATE_NEW_TAG.get(
|
tagName, lineNumber, String.valueOf(e));
|
throw new MakeLDIFException(message, e);
|
}
|
|
|
if (branch == null)
|
{
|
newTag.initializeForTemplate(this, template, args, lineNumber, warnings);
|
}
|
else
|
{
|
if (newTag.allowedInBranch())
|
{
|
newTag.initializeForBranch(this, branch, args, lineNumber, warnings);
|
}
|
else
|
{
|
LocalizableMessage message = ERR_MAKELDIF_TAG_NOT_ALLOWED_IN_BRANCH.get(
|
newTag.getName(), lineNumber);
|
throw new MakeLDIFException(message);
|
}
|
}
|
|
return newTag;
|
}
|
|
|
|
/**
|
* Parses the provided string as an attribute tag. Exactly one of the branch
|
* or template must be null, and the other must be non-null.
|
*
|
* @param tagString The string containing the encoded tag.
|
* @param branch The branch in which this tag appears.
|
* @param template The template in which this tag appears.
|
* @param lineNumber The line number on which this tag appears in the
|
* template file.
|
* @param warnings A list into which any warnings identified may be
|
* placed.
|
*
|
* @return The attribute tag parsed from the provided string.
|
*
|
* @throws InitializationException If a problem occurs while initializing
|
* the tag.
|
*
|
* @throws MakeLDIFException If some other problem occurs during processing.
|
*/
|
private Tag parseAttributeTag(String tagString, Branch branch,
|
Template template, int lineNumber,
|
List<LocalizableMessage> warnings)
|
throws InitializationException, MakeLDIFException
|
{
|
// The attribute tag must have at least one argument, which is the name of
|
// the attribute to reference. It may have a second argument, which is the
|
// number of characters to use from the attribute value. The arguments will
|
// be delimited by colons.
|
StringTokenizer tokenizer = new StringTokenizer(tagString, ":");
|
ArrayList<String> argList = new ArrayList<String>();
|
while (tokenizer.hasMoreTokens())
|
{
|
argList.add(tokenizer.nextToken());
|
}
|
|
String[] args = new String[argList.size()];
|
argList.toArray(args);
|
|
AttributeValueTag tag = new AttributeValueTag();
|
if (branch == null)
|
{
|
tag.initializeForTemplate(this, template, args, lineNumber, warnings);
|
}
|
else
|
{
|
tag.initializeForBranch(this, branch, args, lineNumber, warnings);
|
}
|
|
return tag;
|
}
|
|
|
|
/**
|
* Retrieves a File object based on the provided path. If the given path is
|
* absolute, then that absolute path will be used. If it is relative, then it
|
* will first be evaluated relative to the current working directory. If that
|
* path doesn't exist, then it will be evaluated relative to the resource
|
* path. If that path doesn't exist, then it will be evaluated relative to
|
* the directory containing the template file.
|
*
|
* @param path The path provided for the file.
|
*
|
* @return The File object for the specified path, or <CODE>null</CODE> if
|
* the specified file could not be found.
|
*/
|
public File getFile(String path)
|
{
|
// First, see if the file exists using the given path. This will work if
|
// the file is absolute, or it's relative to the current working directory.
|
File f = new File(path);
|
if (f.exists())
|
{
|
return f;
|
}
|
|
|
// If the provided path was absolute, then use it anyway, even though we
|
// couldn't find the file.
|
if (f.isAbsolute())
|
{
|
return f;
|
}
|
|
|
// Try a path relative to the resource directory.
|
String newPath = resourcePath + File.separator + path;
|
f = new File(newPath);
|
if (f.exists())
|
{
|
return f;
|
}
|
|
|
// Try a path relative to the template directory, if it's available.
|
if (templatePath != null)
|
{
|
newPath = templatePath = File.separator + path;
|
f = new File(newPath);
|
if (f.exists())
|
{
|
return f;
|
}
|
}
|
|
return null;
|
}
|
|
|
|
/**
|
* Retrieves the lines of the specified file as a string array. If the result
|
* is already cached, then it will be used. If the result is not cached, then
|
* the file data will be cached so that the contents can be re-used if there
|
* are multiple references to the same file.
|
*
|
* @param file The file for which to retrieve the contents.
|
*
|
* @return An array containing the lines of the specified file.
|
*
|
* @throws IOException If a problem occurs while reading the file.
|
*/
|
public String[] getFileLines(File file)
|
throws IOException
|
{
|
String absolutePath = file.getAbsolutePath();
|
String[] lines = fileLines.get(absolutePath);
|
if (lines == null)
|
{
|
ArrayList<String> lineList = new ArrayList<String>();
|
|
BufferedReader reader = new BufferedReader(new FileReader(file));
|
while (true)
|
{
|
String line = reader.readLine();
|
if (line == null)
|
{
|
break;
|
}
|
else
|
{
|
lineList.add(line);
|
}
|
}
|
|
reader.close();
|
|
lines = new String[lineList.size()];
|
lineList.toArray(lines);
|
lineList.clear();
|
fileLines.put(absolutePath, lines);
|
}
|
|
return lines;
|
}
|
|
|
|
/**
|
* Generates the LDIF content and writes it to the provided LDIF writer.
|
*
|
* @param entryWriter The entry writer that should be used to write the
|
* entries.
|
*
|
* @return The result that indicates whether processing should continue.
|
*
|
* @throws IOException If an error occurs while writing to the LDIF file.
|
*
|
* @throws MakeLDIFException If some other problem occurs.
|
*/
|
public TagResult generateLDIF(EntryWriter entryWriter)
|
throws IOException, MakeLDIFException
|
{
|
for (Branch b : branches.values())
|
{
|
TagResult result = b.writeEntries(entryWriter);
|
if (! (result.keepProcessingTemplateFile()))
|
{
|
return result;
|
}
|
}
|
|
entryWriter.closeEntryWriter();
|
return TagResult.SUCCESS_RESULT;
|
}
|
}
|