001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2007-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.tools;
028
029import static com.forgerock.opendj.cli.Utils.*;
030import static com.forgerock.opendj.util.OperatingSystem.*;
031
032import static org.opends.messages.ToolMessages.*;
033
034import java.io.File;
035import java.util.LinkedHashSet;
036
037import org.forgerock.i18n.LocalizableMessage;
038import org.opends.quicksetup.Constants;
039import org.opends.quicksetup.Installation;
040import org.opends.quicksetup.util.Utils;
041import org.opends.server.core.DirectoryServer.DirectoryServerVersionHandler;
042
043import com.forgerock.opendj.cli.ArgumentException;
044import com.forgerock.opendj.cli.ArgumentParser;
045import com.forgerock.opendj.cli.BooleanArgument;
046import com.forgerock.opendj.cli.CommonArguments;
047import com.forgerock.opendj.cli.StringArgument;
048
049/**
050 * Class used to parse the arguments of the java properties tool command-line.
051 */
052public class JavaPropertiesToolArgumentParser extends ArgumentParser
053{
054  /** Usage argument. */
055  BooleanArgument   showUsageArg;
056  /** Quiet argument. */
057  BooleanArgument   quietArg;
058  /** The file containing the properties. */
059  StringArgument propertiesFileArg;
060  /** The file that is generated. */
061  StringArgument destinationFileArg;
062
063  /**
064   * The default constructor for this class.
065   * @param mainClassName the class name of the main class for the command-line
066   * that is being used.
067   */
068  public JavaPropertiesToolArgumentParser(String mainClassName)
069  {
070    super(mainClassName,
071        INFO_JAVAPROPERTIES_TOOL_DESCRIPTION.get(getDefaultPropertiesValue()),
072        false);
073    setShortToolDescription(REF_SHORT_DESC_DSJAVAPROPERTIES.get());
074    setVersionHandler(new DirectoryServerVersionHandler());
075  }
076
077  /**
078   * Initializes the arguments without parsing them.
079   * @throws ArgumentException if there was an error creating or adding the
080   * arguments.  If this occurs is likely to be a bug.
081   */
082  public void initializeArguments() throws ArgumentException
083  {
084    quietArg = CommonArguments.getQuiet();
085    addArgument(quietArg);
086
087    propertiesFileArg = new StringArgument("propertiesFile",
088        'p', "propertiesFile", false,
089        false, true, INFO_PATH_PLACEHOLDER.get(), getDefaultPropertiesValue(),
090        "propertiesFile",
091        INFO_JAVAPROPERTIES_DESCRIPTION_PROPERTIES_FILE.get(
092            getDefaultPropertiesValue()));
093    propertiesFileArg.setHidden(true);
094    addArgument(propertiesFileArg);
095
096    destinationFileArg = new StringArgument("destinationFile",
097        'd', "destinationFile", false,
098        false, true, INFO_PATH_PLACEHOLDER.get(), getDefaultDestinationValue(),
099        "destinationFile",
100        INFO_JAVAPROPERTIES_DESCRIPTION_DESTINATION_FILE.get(
101            getDefaultDestinationValue()));
102    destinationFileArg.setHidden(true);
103    addArgument(destinationFileArg);
104
105    showUsageArg = CommonArguments.getShowUsage();
106    addArgument(showUsageArg);
107    setUsageArgument(showUsageArg);
108  }
109
110  /** {@inheritDoc} */
111  @Override
112  public void parseArguments(String[] args) throws ArgumentException
113  {
114    LinkedHashSet<LocalizableMessage> errorMessages = new LinkedHashSet<>();
115    try
116    {
117      super.parseArguments(args);
118    }
119    catch (ArgumentException ae)
120    {
121      errorMessages.add(ae.getMessageObject());
122    }
123
124    if (!isUsageArgumentPresent() && !isVersionArgumentPresent())
125    {
126      String value = propertiesFileArg.getValue();
127      if (value != null)
128      {
129        File f = new File(value);
130        if (!f.exists() || !f.isFile() || !f.canRead())
131        {
132          errorMessages.add(ERR_JAVAPROPERTIES_WITH_PROPERTIES_FILE.get(value));
133        }
134      }
135      value = destinationFileArg.getValue();
136      if (value != null)
137      {
138        File f = new File(value);
139        if (f.isDirectory() || !canWrite(value))
140        {
141          errorMessages.add(
142              ERR_JAVAPROPERTIES_WITH_DESTINATION_FILE.get(value));
143        }
144      }
145      if (!errorMessages.isEmpty())
146      {
147        LocalizableMessage message = ERR_CANNOT_INITIALIZE_ARGS.get(
148            Utils.getMessageFromCollection(errorMessages,
149                Constants.LINE_SEPARATOR));
150        throw new ArgumentException(message);
151      }
152    }
153  }
154
155  /**
156   * Returns the default destination file by inspecting the class loader.
157   * @return the default destination file retrieved by inspecting the class
158   * loader.
159   */
160  private String getDefaultDestinationValue()
161  {
162    // Use this instead of Installation.getLocal() because making that call
163    // starts a new JVM and the command-line becomes less responsive.
164    String installPath = Utils.getInstallPathFromClasspath();
165    String root = Utils.getInstancePathFromInstallPath(installPath);
166    if (root != null)
167    {
168      return getPath(Utils.getPath(root, Installation.LIBRARIES_PATH_RELATIVE));
169    }
170    else
171    {
172      // This can happen when we are not launched using the command-line (for
173      // instance from the WebInstaller).
174      return getPath(Installation.LIBRARIES_PATH_RELATIVE);
175    }
176  }
177
178  private String getPath(String libDir)
179  {
180    final String relativePath = isWindows()
181        ? Installation.SET_JAVA_PROPERTIES_FILE_WINDOWS
182        : Installation.SET_JAVA_PROPERTIES_FILE_UNIX;
183    return Utils.getPath(libDir, relativePath);
184  }
185
186  /**
187   * Returns the default java properties file by inspecting the class loader.
188   * @return the default java properties file retrieved by inspecting the class
189   * loader.
190   */
191  private static String getDefaultPropertiesValue()
192  {
193    // Use this instead of Installation.getLocal() because making that call
194    // starts a new JVM and the command-line becomes less responsive.
195    String installPath = Utils.getInstallPathFromClasspath();
196    String root = Utils.getInstancePathFromInstallPath(installPath);
197    if (root != null)
198    {
199      String configDir = Utils.getPath(root, Installation.CONFIG_PATH_RELATIVE);
200      return Utils.getPath(configDir, Installation.DEFAULT_JAVA_PROPERTIES_FILE);
201    }
202    else
203    {
204      // This can happen when we are not launched using the command-line (for
205      // instance from the WebInstaller).
206      return Installation.DEFAULT_JAVA_PROPERTIES_FILE;
207    }
208  }
209}