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