--- /dev/null
+eclipse.preferences.version=1\r
+encoding/<project>=utf8\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>\r
+<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"\r
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"\r
+ xmlns:target="http://www.samsung.com/schema/profiles"\r
+ targetNamespace="http://www.samsung.com/schema/profiles"\r
+ elementFormDefault="qualified"\r
+ attributeFormDefault="unqualified">\r
+\r
+ <xsd:complexType name="profileitemType">\r
+ <xsd:attribute name="author" type="xsd:string"></xsd:attribute>\r
+ <xsd:attribute name="identifier" type="xsd:string"></xsd:attribute>\r
+ <xsd:attribute name="key" type="xsd:string"></xsd:attribute>\r
+ </xsd:complexType>\r
+\r
+ <xsd:complexType name="profileType">\r
+ <xsd:sequence>\r
+ <xsd:element name="profileitem" type="target:profileitemType" minOccurs="0" maxOccurs="unbounded">\r
+ </xsd:element>\r
+ </xsd:sequence>\r
+ <xsd:attribute name="name" type="xsd:string" use="required"></xsd:attribute>\r
+ </xsd:complexType>\r
+\r
+ <xsd:element name="profiles">\r
+ <xsd:complexType>\r
+ <xsd:sequence>\r
+ <xsd:element name="profile" type="target:profileType" minOccurs="0" maxOccurs="unbounded">\r
+ </xsd:element>\r
+ </xsd:sequence>\r
+ </xsd:complexType>\r
+ </xsd:element>\r
+\r
+\r
+</xsd:schema>\r
*/
package org.tizen.cli.exec;
-import static org.tizen.common.util.StringUtil.nvl;
-
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Enumeration;
+import java.util.Properties;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.tizen.common.file.FileHandler;
import org.tizen.common.file.FileHandler.Attribute;
import org.tizen.common.file.StandardFileHandler;
+import org.tizen.common.util.IOUtil;
import org.tizen.common.util.MapUtil;
+import org.tizen.common.util.PropertyUtil;
/**
* <p>
abstract public class
AbstractLauncher
{
- /**
- * Program name property key
- */
- protected static final String PROP_PRG = "cli.name";
/**
* <p>
*/
protected static final String PROP_PARSER = "tizen.cli.parser";
+
+ /**
+ * <p>
+ * suffix for help properties
+ * </p>
+ */
+ protected static final String SUFFIX_CONFIG = ".properties";
+
/**
* <p>
* logger for this object
/**
* <p>
+ * object for usage help
+ * </p>
+ */
+ protected Help help;
+
+ /**
+ * <p>
* optional flag to be specified by user
*
* flag is formatted in POSIX style in default
*/
protected String getSyntax()
{
- return nvl( System.getProperty( PROP_PRG ), "java " + getClass().getName() );
+ return getHelp().getSyntax();
}
/**
}
/**
+ * <p>
+ * Return {@link Help} in this cli instance
+ * </p>
+ * @return {@link Help}
+ */
+ synchronized protected
+ Help
+ getHelp()
+ {
+ if ( null == help )
+ {
+ this.help = new Help( getOptions() );
+ final ClassLoader cl = getClass().getClassLoader();
+ final String resourceName = getClass().getName().replace( '.', '/' ) + SUFFIX_CONFIG;
+ try
+ {
+ final Enumeration<URL> iter = cl.getResources( resourceName );
+ while ( iter.hasMoreElements() )
+ {
+ final URL url = iter.nextElement();
+ final Properties properties = PropertyUtil.loadProperties( url.openStream() );
+
+ for ( final Object key : properties.keySet() )
+ {
+ final String value = properties.getProperty( (String) key );
+ byte[] contents = IOUtil.getBytes( cl.getResourceAsStream( value ), true );
+ this.help.addHelpDetail( (String) key, new String( contents, Charset.forName( "utf8" ) ) );
+ }
+ }
+ }
+ catch ( final IOException e )
+ {
+ logger.warn( "Can't load help", e );
+ }
+ }
+
+ return this.help;
+ }
+
+ /**
+ * Print out sample usage
+ *
+ * @return sample usage string
+ */
+ protected
+ String
+ printHelpDetail( String option )
+ {
+ return getHelp().getHelpDetail( option );
+ }
+
+ /**
* Print out usage
*
* @return usage string
String
printHelp()
{
- final HelpFormatter formatter = new HelpFormatter();
-
- final StringWriter writer = new StringWriter();
-
- final PrintWriter stream = new PrintWriter( writer );
-
- formatter.printHelp(
- stream,
- formatter.getWidth(),
- getSyntax(),
- null,
- getOptions(),
- formatter.getLeftPadding(),
- formatter.getDescPadding(),
- null,
- false
- );
-
- final String help = writer.toString();
-
- getPrompter().error( help );
-
- return help;
+ String helpStr = getHelp().getHelp();
+ getPrompter().error( helpStr );
+ return helpStr;
}
if ( cmd.hasOption( OPT_HELP ) )
{
printHelp();
+
+ for ( String keyword : cmd.getArgs() )
+ {
+ printHelpDetail( keyword );
+ }
return ;
}
-
+
execute( cmd );
}
catch ( final ParseException e )
--- /dev/null
+package org.tizen.cli.exec;\r
+\r
+import static org.tizen.common.util.StringUtil.EMPTY_STRING;\r
+import static org.tizen.common.util.StringUtil.nvl;\r
+\r
+import java.io.PrintWriter;\r
+import java.io.StringWriter;\r
+import java.util.HashMap;\r
+\r
+import org.apache.commons.cli.HelpFormatter;\r
+import org.apache.commons.cli.Options;\r
+\r
+public class Help\r
+{\r
+ /**\r
+ * Program name property key\r
+ */\r
+ protected static final String PROP_PRG = "cli.name";\r
+ \r
+ protected final Options opts;\r
+ \r
+ protected HashMap<String, String> keyword2help = new HashMap<String, String>();\r
+ \r
+ public Help( Options opts )\r
+ {\r
+ this.opts = opts;\r
+ }\r
+ \r
+ /**\r
+ * {@link Options} for usage\r
+ * \r
+ * @return defined {@link Options}\r
+ */\r
+ protected\r
+ Options\r
+ getOptions()\r
+ {\r
+ return opts;\r
+ }\r
+ \r
+ public void addHelpDetail( String keyword, String help )\r
+ {\r
+ keyword2help.put( keyword.toLowerCase(), help );\r
+ }\r
+ \r
+ /**\r
+ * return execution command for usage\r
+ * \r
+ * @return execution command\r
+ */\r
+ protected String getSyntax()\r
+ {\r
+ return nvl( System.getProperty( PROP_PRG ), "java " + getClass().getName() );\r
+ }\r
+\r
+ \r
+ public String getHelp()\r
+ {\r
+ final HelpFormatter formatter = new HelpFormatter();\r
+\r
+ final StringWriter writer = new StringWriter();\r
+\r
+ final PrintWriter stream = new PrintWriter( writer );\r
+\r
+ formatter.printHelp(\r
+ stream,\r
+ formatter.getWidth(),\r
+ getSyntax(),\r
+ null,\r
+ getOptions(),\r
+ formatter.getLeftPadding(),\r
+ formatter.getDescPadding(),\r
+ null,\r
+ false\r
+ );\r
+ \r
+ final String help = writer.toString();\r
+ \r
+ return help;\r
+ }\r
+ \r
+ public String\r
+ getHelpDetail( final String keyword )\r
+ {\r
+ if ( null == keyword )\r
+ {\r
+ return EMPTY_STRING;\r
+ }\r
+ return nvl( keyword2help.get( keyword.toLowerCase() ) );\r
+ }\r
+\r
+}\r
package org.tizen.cli.exec.sign;
import static org.tizen.common.util.FilenameUtil.addTailingPath;
+import static org.tizen.common.util.StringUtil.nvl;
import java.io.IOException;
import java.text.MessageFormat;
import org.tizen.common.file.FileHandler;
import org.tizen.common.file.FileHandler.Attribute;
import org.tizen.common.util.CollectionUtil;
+import org.tizen.common.util.FilenameUtil;
import org.tizen.web.sign.command.ReadSigningProfileFileCommand;
import org.tizen.web.sign.command.SignCommand;
*/
protected static final int SEPARATOR_PROFILE = ':';
+
+ /**
+ * <p>
+ * JVM property key for default profile path
+ * </p>
+ */
+ protected static final String PROP_CLI_HOME = "cli.home";
+
+ /**
+ * <p>
+ * OS environment variable key for default profile path
+ * </p>
+ */
+ protected static final String ENV_CLI_HOME = "CLI_HOME";
+
+ /**
+ * <p>
+ * default profile file's name
+ * </p>
+ */
+ protected static final String DEFAULT_PROFILE_NAME = "profiles.xml";
+
/**
* Entry point for cli main
*
final int index = profileName.indexOf( SEPARATOR_PROFILE );
if ( index < 0 )
{
- profilesFilePath = System.getProperty( "user.home" ) + "/.tizen/profiles.xml";
+ profilesFilePath = getDefaultProfilesFilePath();
}
else
{
logger.debug( "Profile name :{}", profileName );
logger.debug( "Profiles file path :{}", profilesFilePath );
+ if ( null == profilesFilePath )
+ {
+ getExecutionContext().getPrompter().error( "Profiles file not found. Try to specify profiles path using -p option or environment variable cli.home" );
+ return ;
+ }
final ReadSigningProfileFileCommand readProfile = new ReadSigningProfileFileCommand( profilesFilePath, profileName );
getExecutor().execute( readProfile );
}
/**
+ * Return default profiles.xml's path
+ *
+ * default profile path is specified by jvm propertyes naming "cli.home"
+ *
+ * or os environment variable "CLI_HOME"
+ *
+ * @return default profiles path
+ */
+ protected
+ String
+ getDefaultProfilesFilePath()
+ {
+ final String cliHome =
+ nvl( System.getProperty( PROP_CLI_HOME ), System.getenv( ENV_CLI_HOME ) );
+
+ if ( null == cliHome )
+ {
+ return null;
+ }
+
+ return FilenameUtil.addTailingPath( cliHome, "conf/" + DEFAULT_PROFILE_NAME );
+ }
+
+ /**
* Check if <code>path</code> is Tizen web project root
*
* @param path directory path to check
--- /dev/null
+profile=org/tizen/cli/exec/sign/profile.help
\ No newline at end of file
--- /dev/null
+Specify profile( profile name and profiles file path )\r
+\r
+* profile name\r
+ Profiles file can contain multiple profiles. You must specify profile to use in signing.\r
+\r
+* profiles file path\r
+ Path of profiles file containing profiles. Default value is "$CLI_HOME/conf/profiles.xml". You can change it using java virtual machine properties( -D ).\r
+\r
+ Ex.)\r
+ web-signing -p develop:/home/tizen/profiles.xml\r
+\r
+* profiles file format\r
+ It is xml-formatted file. Its schema( xml schema ) exists in $CLI_HOME/doc/schema/profiles.xsd\r
+ You don't have to specify schema in profiles file
\ No newline at end of file
*/
package org.tizen.cli.exec;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.tizen.cli.exec.sign.Main;
import org.tizen.common.core.command.Executor;
import org.tizen.common.core.command.prompter.NopPrompter;
*/
public LauncherSpi() {
executor = new CommandLineExecutor( new NopPrompter() );
+ getHelp().addHelpDetail( "hello", "World" );
}
/* (non-Javadoc)
assertNotNull( launcher.printHelp() );
}
+ @Test
+ public
+ void
+ test_printHelpDetail()
+ throws Exception
+ {
+ assertEquals( "World", launcher.printHelpDetail( "Hello" ) );
+ }
+
/**
* Test {@link AbstractLauncher#run(String...)}
*
assertNotNull( executor );
}
+ /**
+ * Test {@link AbstractLauncher#getHelp()}
+ *
+ * @throws Exception in case of failure in test
+ *
+ * @see AbstractLauncher#getHelp()
+ */
+ @Test
+ public
+ void
+ test_getHelp()
+ throws Exception
+ {
+ final Main testTarget = new Main();
+
+ final Help help = testTarget.getHelp();
+ assertNotNull( help );
+
+ assertTrue( help.getHelpDetail( "profile" ).contains( "profiles.xsd" ) );
+
+ }
+
}
--- /dev/null
+/*\r
+* Command Line Interface\r
+*\r
+* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+*\r
+* Contact: \r
+* BonYong Lee <bonyong.lee@samsung.com>\r
+* \r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*\r
+* Contributors:\r
+* - S-Core Co., Ltd\r
+*\r
+*/\r
+package org.tizen.cli.exec;\r
+\r
+import static org.junit.Assert.*;\r
+\r
+import org.apache.commons.cli.OptionBuilder;\r
+import org.apache.commons.cli.Options;\r
+import org.junit.Test;\r
+\r
+/**\r
+ * HelpTest\r
+ *\r
+ * Test case for {@link Help}\r
+ * \r
+ * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
+ * \r
+ * @see Help\r
+ */\r
+public class HelpTest\r
+{\r
+\r
+ /**\r
+ * Test {@link Help#getHelp()}\r
+ * \r
+ * @throws Exception in case of failure in test\r
+ * \r
+ * @see Help#getHelp()\r
+ */\r
+ @SuppressWarnings("static-access")\r
+ @Test\r
+ public void test_getHelp()\r
+ {\r
+ \r
+ final Help h = new Help( new Options().addOption( OptionBuilder.withLongOpt( "help" ).create( "h" ) ) );\r
+ \r
+ assertNotNull( h.getHelp() );\r
+ assertTrue( h.getHelp().contains( "-h,--help" ) );\r
+ }\r
+ \r
+ /**\r
+ * Test {@link Help#getHelpDetail(String)}\r
+ * \r
+ * @throws Exception in case of failure in test\r
+ * \r
+ * @see Help#getHelpDetail(String)\r
+ */\r
+ @SuppressWarnings("static-access")\r
+ public void test_getHelpDetail() throws Exception\r
+ {\r
+ final Help h = new Help( new Options().addOption( OptionBuilder.withLongOpt( "help" ).create( "h" ) ) );\r
+ h.addHelpDetail( "command", "command is not supported" );\r
+ \r
+ \r
+ assertEquals( "command is not supported", h.getHelpDetail( "command" ) );\r
+ \r
+ \r
+ }\r
+\r
+}\r
*/
package org.tizen.cli.exec;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mockito;
import org.tizen.common.core.command.Prompter;
import org.tizen.common.core.command.prompter.ChoiceOption;
import org.tizen.common.core.command.prompter.GenericOption;
import org.tizen.sdblib.IDevice;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
/**
* TargetDeviceSelectorTest
*
)
).thenReturn( no );
ChoiceOption cancel = new ChoiceOption( "Cancel", true );
- GenericOption num = new GenericOption( "Num" );
- when( mockPropter.interact( "select device or cancel process ",
- cancel,
- num
+ when( mockPropter.interact( Mockito.eq( "select device or cancel process " ),
+ Mockito.<ChoiceOption>any(),
+ Mockito.<GenericOption>any()
)
).thenReturn( cancel );
assertEquals( null, testClass.selectDevice() );