[225866] Console Editor for updating connection profile properties in an exported file
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/.classpath b/plugins/org.eclipse.datatools.connectivity.console.profile/.classpath
new file mode 100644
index 0000000..2fbb7a2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.4"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/.cvsignore b/plugins/org.eclipse.datatools.connectivity.console.profile/.cvsignore
new file mode 100644
index 0000000..0cd6cd2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/.cvsignore
@@ -0,0 +1,5 @@
+bin
+download
+.settings
+*.jar
+*.zip
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/.project b/plugins/org.eclipse.datatools.connectivity.console.profile/.project
new file mode 100644
index 0000000..4dc11b0
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.datatools.connectivity.console.profile</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
+ </natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/META-INF/MANIFEST.MF b/plugins/org.eclipse.datatools.connectivity.console.profile/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..28e05fb
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/META-INF/MANIFEST.MF
@@ -0,0 +1,13 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %plugin.name
+Bundle-SymbolicName: org.eclipse.datatools.connectivity.console.profile;singleton:=true
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: Eclipse.org
+Bundle-RequiredExecutionEnvironment: J2SE-1.4
+Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.3.0,4.0.0)",
+ org.eclipse.datatools.connectivity;bundle-version="[1.1.0,2.0.0)",
+ org.eclipse.datatools.connectivity.oda;bundle-version="[3.1.2,4.0.0)"
+Eclipse-LazyStart: true
+Bundle-ActivationPolicy: lazy
+Bundle-Localization: plugin
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/about.html b/plugins/org.eclipse.datatools.connectivity.console.profile/about.html
new file mode 100644
index 0000000..4602330
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/about.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+
+<p>June 2, 2006</p>
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content. Check the Redistributor's license that was
+provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/build.properties b/plugins/org.eclipse.datatools.connectivity.console.profile/build.properties
new file mode 100644
index 0000000..1e854e2
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/build.properties
@@ -0,0 +1,10 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ plugin.xml,\
+ about.html,\
+ plugin.properties,\
+ readme.txt
+src.includes = about.html,\
+ readme.txt
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/plugin.properties b/plugins/org.eclipse.datatools.connectivity.console.profile/plugin.properties
new file mode 100644
index 0000000..b4307a4
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/plugin.properties
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2008 Actuate Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Actuate Corporation - initial API and implementation
+#
+###############################################################################
+# NLS String
+###############################################################################
+#
+plugin.name=DTP Connection Profiles Storage File Editor Plug-in
+application.name=DTP Connection Profiles Console Editor
+
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/plugin.xml b/plugins/org.eclipse.datatools.connectivity.console.profile/plugin.xml
new file mode 100644
index 0000000..83f5aa3
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/plugin.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.2"?>
+<plugin>
+ <extension
+ id="StorageFileEditor"
+ name="%application.name"
+ point="org.eclipse.core.runtime.applications">
+ <application
+ cardinality="*"
+ thread="main"
+ visible="true">
+ <run
+ class="org.eclipse.datatools.connectivity.console.profile.internal.EditorCmdAppl">
+ </run>
+ </application>
+ </extension>
+
+</plugin>
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/readme.txt b/plugins/org.eclipse.datatools.connectivity.console.profile/readme.txt
new file mode 100644
index 0000000..29faae7
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/readme.txt
@@ -0,0 +1,45 @@
+###############################################################################
+# Copyright (c) 2008 Actuate Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Actuate Corporation - initial API and implementation
+#
+###############################################################################
+
+This Data Tools Platform (DTP) plug-in provides a console editor application for users to
+view and update the contents of an exported file containing DTP connection profiles.
+
+It is intended for use at a system console to make minor changes to an exported connection profile,
+such as the file path of JDBC driver jars, a connection URL, an ODA data source file path, etc.
+When an exported file is copied to a server platform for deployment, an user can use
+this editor tool to quickly adjust the connection profile properties without having to
+bring up the DTP Data Source Explorer UI workbench. Any user updates are saved in
+a separate file for all the connection profiles.
+
+To use the tool, make sure the plug-in jar
+(org.eclipse.datatools.connectivity.console.profile_<version>.jar) is installed in
+your Eclipse environment, together with the other DTP plug-ins.
+From within your Eclipse home directory, enter the command in the system console
+using the syntax described below.
+(Note that it could take a good number of seconds for the Eclipse executable to start up.)
+
+Command syntax:
+ eclipse[c] -nosplash -application org.eclipse.datatools.connectivity.console.profile.StorageFileEditor
+ [ -? |
+ -in <connectionProfileFile> |
+ -out <saveAsFile> |
+ -profile <profileName> ]
+
+Use "eclipsec" in command on Windows, or "eclipse" on other platforms.
+
+Optional command line arguments:
+ -? : displays this help message
+ -in <connectionProfileFile> : specifies the name of the connection profile storage file to view/change
+ -out <saveAsFile> : specifies the name of the output file to save your changes
+ -profile <profileName> : specifies the name of a connection profile to view/change; if none is specified,
+ the tool will step through all the profiles found in the input file
+ If an argument value is not specified, the editor will prompt for an input value.
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/EditorCmdAppl.java b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/EditorCmdAppl.java
new file mode 100644
index 0000000..68239e5
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/EditorCmdAppl.java
@@ -0,0 +1,257 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2008 Actuate Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Actuate Corporation - initial API and implementation
+ *
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.console.profile.internal;
+
+import java.io.File;
+
+import org.eclipse.datatools.connectivity.console.profile.nls.Messages;
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+
+/**
+ * Command-line editor application to view and update the contents of an exported file
+ * containing DTP connection profiles.
+ */
+public class EditorCmdAppl implements IApplication
+{
+ private static final String INPUT_FILE_ARG_KEY = "-in"; //$NON-NLS-1$
+ private static final String OUTPUT_FILE_ARG_KEY = "-out"; //$NON-NLS-1$
+ private static final String PROFILE_NAME_ARG_KEY = "-profile"; //$NON-NLS-1$
+ private static final String HELP_SYNTAX = "-?"; //$NON-NLS-1$
+
+ private static final String APPLICATION_ID = "StorageFileEditor"; //$NON-NLS-1$
+ private static final int NUM_PROMPT_FILE_RETRY = 3;
+
+ private File m_inFile;
+ private File m_outFile;
+ private String m_editProfileName;
+ private SystemIOUtil m_ioUtil = new SystemIOUtil();
+
+ /* (non-Javadoc)
+ * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
+ */
+ public Object start( IApplicationContext context ) throws Exception
+ {
+ m_ioUtil.printNewLine( Messages.bind( Messages.editorAppl_startAppl, APPLICATION_ID ));
+
+ processCmdArguments( context );
+
+ // no valid input or output file specified in command line arguments
+ if( m_inFile == null )
+ {
+ m_inFile = promptForInputFile();
+ if( m_inFile == null )
+ return normalExit();
+ }
+ if( m_outFile == null )
+ {
+ m_outFile = promptForOutputFile();
+ if( m_outFile == null )
+ return normalExit();
+ }
+
+ if( m_editProfileName == null )
+ m_editProfileName = promptForProfileName();
+
+ // read and process the specified input file; and save in specified output file
+
+ ProfileFileProcessor handler = new ProfileFileProcessor( m_ioUtil );
+ int numProfiles = handler.loadProfileFile( m_inFile );
+ if( numProfiles == 0 )
+ return normalExit();
+
+ boolean hasUpdates = handler.updateProfiles( m_editProfileName );
+ if( hasUpdates )
+ handler.saveUpdatedProfiles( m_outFile );
+ else
+ m_ioUtil.println( Messages.editorAppl_noProfileChanges );
+
+ return normalExit();
+ }
+
+ private Object normalExit()
+ {
+ m_ioUtil.println( Messages.bind( Messages.editorAppl_exitAppl, APPLICATION_ID ));
+ return EXIT_OK;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.equinox.app.IApplication#stop()
+ */
+ public void stop()
+ {
+ }
+
+ private void processCmdArguments( IApplicationContext context )
+ {
+ String[] args = (String[]) context.getArguments().get( IApplicationContext.APPLICATION_ARGS );
+
+ if( args.length == 0 ) // has no arguments
+ return;
+
+ for( int i=0; i < args.length; i++ )
+ {
+ String arg = args[i];
+
+ if( arg.equalsIgnoreCase( INPUT_FILE_ARG_KEY ) )
+ {
+ if( (i+1) >= args.length ) // no more arguments available
+ printMissingArgumentError( INPUT_FILE_ARG_KEY );
+ else // has input argument value
+ {
+ // get next argument for input file name
+ String inFileName = (String) args[++i];
+ printArgumentValue( INPUT_FILE_ARG_KEY, inFileName );
+ m_inFile = validateInputFile( inFileName );
+ }
+ }
+ else if( arg.equalsIgnoreCase( OUTPUT_FILE_ARG_KEY ) )
+ {
+ if( (i+1) >= args.length ) // no more arguments available
+ printMissingArgumentError( OUTPUT_FILE_ARG_KEY );
+ else // has output argument value
+ {
+ // get next argument for output file name
+ String outFileName = (String) args[++i];
+ printArgumentValue( OUTPUT_FILE_ARG_KEY, outFileName );
+ m_outFile = validateOutputFile( outFileName );
+ }
+ }
+ else if( arg.equalsIgnoreCase( PROFILE_NAME_ARG_KEY ) )
+ {
+ if( (i+1) >= args.length ) // no more arguments available
+ printMissingArgumentError( PROFILE_NAME_ARG_KEY );
+ else // has profile name argument value
+ {
+ // get next argument for argument value
+ m_editProfileName = (String) args[++i];
+ printArgumentValue( PROFILE_NAME_ARG_KEY, m_editProfileName );
+ }
+ }
+ else if( arg.equalsIgnoreCase( HELP_SYNTAX ) )
+ {
+ printCommandSyntax();
+ }
+ }
+ }
+
+ private void printMissingArgumentError( String argKey )
+ {
+ m_ioUtil.println( Messages.bind( Messages.editorAppl_missingArgValue, argKey ));
+ }
+
+ private void printArgumentValue( String argKey, String argValue )
+ {
+ m_ioUtil.println( Messages.bind( Messages.editorAppl_argKeyValue, argKey, argValue ));
+ }
+
+ private File validateInputFile( String inFileName )
+ {
+ if( inFileName.trim().length() == 0 )
+ {
+ m_ioUtil.println( Messages.bind( Messages.editorAppl_invalidFileName, inFileName ) );
+ return null;
+ }
+
+ File inFile = new File( inFileName );
+ if( inFile.exists() && inFile.isFile() )
+ return inFile;
+
+ // invalid input file
+ String errorMsg = Messages.bind( Messages.editorAppl_invalidInputFile, inFile.getAbsoluteFile() );
+ m_ioUtil.println( errorMsg );
+ return null;
+ }
+
+ private File validateOutputFile( String outFileName )
+ {
+ if( outFileName.trim().length() == 0 )
+ {
+ m_ioUtil.println( Messages.bind( Messages.editorAppl_invalidFileName, outFileName ) );
+ return null;
+ }
+
+ File outFile = new File( outFileName );
+ if( ! outFile.exists() ) // a non-existing output file
+ return outFile; // ok to use it
+
+ // outfile already exists
+ if( outFile.isFile() )
+ {
+ if( m_ioUtil.promptYesNoResponse( Messages.bind( Messages.editorAppl_overwriteExistingFile,
+ outFile.getAbsoluteFile() ) ))
+ return outFile;
+ }
+
+ // invalid output file to use
+ String errorMsg = Messages.bind( Messages.editorAppl_invalidOutputFile, outFile.getAbsoluteFile() );
+ m_ioUtil.println( errorMsg );
+ return null;
+ }
+
+ private File promptForInputFile()
+ {
+ String inFileName;
+ File inFile = null;
+ m_ioUtil.printNewLine();
+ for( int i=0; inFile == null && i < NUM_PROMPT_FILE_RETRY; i++ )
+ {
+ inFileName = m_ioUtil.promptForInput( Messages.editorAppl_promptInputFile );
+ inFile = validateInputFile( inFileName );
+ }
+ return inFile;
+ }
+
+ private File promptForOutputFile()
+ {
+ String outFileName;
+ File outFile = null;
+ m_ioUtil.printNewLine();
+ for( int i=0; outFile == null && i < NUM_PROMPT_FILE_RETRY; i++ )
+ {
+ outFileName = m_ioUtil.promptForInput( Messages.editorAppl_promptOutputFile );
+ outFile = validateOutputFile( outFileName );
+ }
+ return outFile;
+ }
+
+ private String promptForProfileName()
+ {
+ m_ioUtil.printNewLine();
+ return m_ioUtil.promptForInput( Messages.editorAppl_promptEditProfileName );
+ }
+
+ private void printCommandSyntax()
+ {
+ m_ioUtil.printNewLine( Messages.editorAppl_syntaxUsage );
+ m_ioUtil.println( " eclipse[c] -nosplash -application org.eclipse.datatools.connectivity.console.profile.StorageFileEditor" ); //$NON-NLS-1$
+ // "[ -? | -in <connectionProfileFile> | -out <saveInFile> | -profile <profileName> ]"
+ m_ioUtil.println( " [ " + HELP_SYNTAX + " |" ); //$NON-NLS-1$ //$NON-NLS-2$
+ m_ioUtil.println( " " + INPUT_FILE_ARG_KEY + " <connectionProfileFile> |" ); //$NON-NLS-1$ //$NON-NLS-2$
+ m_ioUtil.println( " " + OUTPUT_FILE_ARG_KEY + " <saveAsFile> |" ); //$NON-NLS-1$ //$NON-NLS-2$
+ m_ioUtil.println( " " + PROFILE_NAME_ARG_KEY + " <profileName> ]" ); //$NON-NLS-1$ //$NON-NLS-2$
+
+ m_ioUtil.printNewLine( Messages.editorAppl_syntaxCommand );
+ m_ioUtil.printNewLine( Messages.editorAppl_syntaxArguments);
+ m_ioUtil.println( " " + HELP_SYNTAX + " : " + Messages.editorAppl_syntaxHelpInstruction ); //$NON-NLS-1$ //$NON-NLS-2$
+ m_ioUtil.println( " " + INPUT_FILE_ARG_KEY + " <connectionProfileFile> : " + Messages.editorAppl_syntaxInArgInstruction ); //$NON-NLS-1$ //$NON-NLS-2$
+ m_ioUtil.println( " " + OUTPUT_FILE_ARG_KEY + " <saveAsFile> : " + Messages.editorAppl_syntaxOutArgInstruction ); //$NON-NLS-1$ //$NON-NLS-2$
+ m_ioUtil.println( " " + PROFILE_NAME_ARG_KEY + " <profileName> : " + Messages.editorAppl_syntaxProfileNameInstruction1 ); //$NON-NLS-1$//$NON-NLS-2$
+ m_ioUtil.println( " " + Messages.editorAppl_syntaxProfileNameInstruction2 ); //$NON-NLS-1$
+ m_ioUtil.println( " " + Messages.editorAppl_syntaxNullArgInstruction ); //$NON-NLS-1$
+ m_ioUtil.printNewLine();
+ }
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/ProfileFileProcessor.java b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/ProfileFileProcessor.java
new file mode 100644
index 0000000..09b39e3
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/ProfileFileProcessor.java
@@ -0,0 +1,431 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2008 Actuate Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Actuate Corporation - initial API and implementation
+ *
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.console.profile.internal;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.datatools.connectivity.IConnectionProfile;
+import org.eclipse.datatools.connectivity.console.profile.nls.Messages;
+import org.eclipse.datatools.connectivity.drivers.IDriverMgmtConstants;
+import org.eclipse.datatools.connectivity.drivers.jdbc.IJDBCConnectionProfileConstants;
+import org.eclipse.datatools.connectivity.internal.CategoryProvider;
+import org.eclipse.datatools.connectivity.internal.ConnectionProfileMgmt;
+import org.eclipse.datatools.connectivity.internal.security.ICipherProvider;
+import org.eclipse.datatools.connectivity.internal.security.SecurityManager;
+import org.eclipse.datatools.connectivity.oda.util.manifest.ExtensionManifest;
+import org.eclipse.datatools.connectivity.oda.util.manifest.ManifestExplorer;
+import org.eclipse.datatools.connectivity.oda.util.manifest.Property;
+
+/**
+ * Responsible for processing a connection profile storage file,
+ * such as reading a storage file, interacting with an user to
+ * view or change its content, and saving user changes.
+ */
+public class ProfileFileProcessor
+{
+ private static final String PROP_PROMPT_DELIMITER = Messages.profileFile_inputPromptDelimiter;
+ private static final String PROFILE_LINE_SEPARATOR = "-----------------------------"; //$NON-NLS-1$
+
+ private SystemIOUtil m_ioUtil;
+ private IConnectionProfile[] m_profiles;
+ private ICipherProvider m_cipherProvider = null;
+ private boolean m_wasInputFileEncrypted;
+ private PropertyEditor m_propEditor = new PropertyEditor();
+
+ ProfileFileProcessor( SystemIOUtil util )
+ {
+ if( util == null )
+ throw new IllegalArgumentException( "ProfileFileHandler( null )" ); //$NON-NLS-1$
+ m_ioUtil = util;
+ }
+
+ /**
+ * Loads the specified connection profile storage file.
+ * Tracks whether the specified file was encrypted.
+ * @param inFile
+ * @return the number of profiles read from file
+ */
+ int loadProfileFile( File inFile )
+ {
+ m_ioUtil.printNewLine();
+ m_ioUtil.println( Messages.bind( Messages.profileFile_statusReadingFile, inFile.getAbsolutePath() ) );
+
+ try
+ {
+ m_wasInputFileEncrypted = ConnectionProfileMgmt.isEncrypted( inFile );
+ ICipherProvider cipherProvider = m_wasInputFileEncrypted ?
+ getCipherProvider() :
+ null;
+ m_profiles = ConnectionProfileMgmt.loadCPs( inFile, cipherProvider );
+ }
+ catch( Exception ex )
+ {
+ m_ioUtil.printException( Messages.profileFile_errorReadingFile, ex );
+ m_ioUtil.println( Messages.profileFile_errorInstruction );
+ return 0;
+ }
+
+ if( m_profiles == null || m_profiles.length == 0 )
+ m_ioUtil.println( Messages.profileFile_noProfileFound );
+
+ return ( m_profiles == null ) ? 0 : m_profiles.length;
+ }
+
+ private ICipherProvider getCipherProvider()
+ {
+ if( m_cipherProvider == null )
+ m_cipherProvider = SecurityManager.getInstance().getDefaultCipherProvider();
+ return m_cipherProvider;
+ }
+
+ /**
+ * Saves the current state of all the profile instances into the specified output file.
+ * This is normally called after the profiles have been updated by {@link #updateProfiles(String)}.
+ * If the input file read by {@link #loadProfileFile(File)} was encrypted, the output file
+ * is automatically saved in encrypted format.
+ * Otherwise, gives user a choice to encrypt the output file.
+ * @param outFile
+ */
+ void saveUpdatedProfiles( File outFile )
+ {
+ ICipherProvider cipherProvider = null;
+ if( m_wasInputFileEncrypted ) // input file was encrypted
+ cipherProvider = getCipherProvider(); // must save in encrypted format
+ else
+ {
+ // give user a choice to save in encrypted format
+ if( m_ioUtil.promptYesNoResponse( Messages.profileFile_askEncryptOutput ) )
+ cipherProvider = getCipherProvider();
+ }
+
+ // proceed to save
+ m_ioUtil.printNewLine();
+ m_ioUtil.println( Messages.bind( Messages.profileFile_statusSavingFile, outFile.getAbsoluteFile() ));
+ try
+ {
+ ConnectionProfileMgmt.saveCPs( m_profiles, outFile, cipherProvider );
+ }
+ catch( CoreException ex )
+ {
+ m_ioUtil.printException( Messages.profileFile_errorSavingFile, ex );
+ return;
+ }
+
+ m_ioUtil.println( Messages.profileFile_statusDone );
+ }
+
+ /**
+ * Interacts with an user to view and update each of the connection profile instance(s)
+ * found in the input file specified in {@link #loadProfileFile(File)}.
+ * @param profileName The name of a connection profile. If a name is specified,
+ * only that profile instance if found, will be promped for updates.
+ * A null value indicates to update all connection profile instances in the input file.
+ * @return true if at least one profile has updates made to its properties; false otherwise
+ */
+ boolean updateProfiles( String profileName )
+ {
+ final boolean editingSingleProfile = profileName != null && profileName.trim().length() > 0;
+
+ if( m_profiles == null || m_profiles.length == 0 )
+ {
+ if( editingSingleProfile )
+ m_ioUtil.printNewLine( Messages.bind( Messages.profileFile_specifiedProfileNotFound, profileName ));
+ return false;
+ }
+
+ if( ! editingSingleProfile )
+ m_ioUtil.println( Messages.bind( Messages.profileFile_statusIteratingProfiles,
+ new Integer( m_profiles.length ) ));
+
+ boolean foundNamedProfile = false;
+ boolean hasUpdates = false;
+ for( int i = 0; i < m_profiles.length && ! foundNamedProfile; i++ )
+ {
+ IConnectionProfile profile = m_profiles[i];
+ if( editingSingleProfile )
+ {
+ if( ! profile.getName().equalsIgnoreCase( profileName ) )
+ continue;
+ foundNamedProfile = true;
+ }
+
+ // prompt whether to update this profile instance
+ m_ioUtil.printNewLine( PROFILE_LINE_SEPARATOR );
+
+ String profileType = profile.getProvider().getCategory().getId().equals( CategoryProvider.ID_CATEGORY_UNKNOWN ) ?
+ profile.getProviderId() : profile.getProviderName();
+ m_ioUtil.println( Messages.bind( Messages.profileFile_profileIdentifier, profileType )
+ + PROP_PROMPT_DELIMITER + profile.getName() );
+ if( ! m_ioUtil.promptYesNoResponse( Messages.profileFile_askUpdateProfile ) )
+ continue;
+
+ Properties props = profile.getBaseProperties();
+ if( props.getProperty( IJDBCConnectionProfileConstants.DRIVER_CLASS_PROP_ID ) != null ) // has DB property
+ hasUpdates |= updateDatabaseProperties( profile );
+ else
+ hasUpdates |= updateOdaProfileProperties( profile );
+ }
+
+ if( editingSingleProfile && ! foundNamedProfile )
+ m_ioUtil.printNewLine( Messages.bind( Messages.profileFile_specifiedProfileNotFound, profileName ));
+ m_ioUtil.println( Messages.profileFile_statusDone );
+ return hasUpdates;
+ }
+
+ private boolean updateDatabaseProperties( IConnectionProfile profile )
+ {
+ return DatabaseProfileHandler.updateProfileProperties( profile, m_propEditor );
+ }
+
+ private boolean updateOdaProfileProperties( IConnectionProfile profile )
+ {
+ return OdaProfileHandler.updateProfileProperties( profile, m_propEditor );
+ }
+
+ /**
+ * Responsbile for interacting with users to view and edit a property.
+ */
+ private class PropertyEditor
+ {
+ private static final String MASKED_VALUE = "*****"; //$NON-NLS-1$
+ private static final String NULL_DISPLAY_VALUE = "<null>"; //$NON-NLS-1$
+ private static final String VALUE_DELIMITER = "\""; //$NON-NLS-1$
+ /**
+ * Gets and displays the current value of the specified propertyKey and
+ * interacts with user to input a new value.
+ * The password property value is masked when displayed.
+ */
+ private String promptNewPropertyValue( Properties props, String propertyKey, String propertyDisplayName )
+ {
+ boolean maskValue = propertyKey.equals( IJDBCConnectionProfileConstants.PASSWORD_PROP_ID );
+ return promptNewPropertyValue( props, propertyKey, propertyDisplayName, maskValue );
+ }
+
+ /**
+ * Gets and displays the current value of the specified propertyKey; mask the current value if specfied,
+ * and interacts with user to input a new value.
+ */
+ private String promptNewPropertyValue( Properties props, String propertyKey, String propertyDisplayName, boolean maskValue )
+ {
+ String propValue = maskValue ? MASKED_VALUE : props.getProperty( propertyKey );
+ return promptNewPropertyValue( propertyDisplayName, propValue );
+ }
+
+ /**
+ * Displays the specified current value, and interacts with user to input a new value.
+ * A null value is displayed as "<null>". An empty string value or one with only spaces
+ * is delimited by double-quotes.
+ */
+ private String promptNewPropertyValue( String propertyDisplayName, String currentValue )
+ {
+ String displayValue = currentValue;
+ if( displayValue == null )
+ displayValue = NULL_DISPLAY_VALUE;
+ else if( displayValue.trim().length() == 0 ) // wraps empty string or spaces with delimiters
+ displayValue = VALUE_DELIMITER + displayValue + VALUE_DELIMITER;
+
+ m_ioUtil.printNewLine( propertyDisplayName + PROP_PROMPT_DELIMITER + displayValue );
+ return m_ioUtil.promptForUpdateValue();
+ }
+
+ private boolean setNewPropertyValue( Properties props, String key, String newValue )
+ {
+ if( newValue != null )
+ {
+ props.setProperty( key, newValue );
+ return true;
+ }
+ return false;
+ }
+
+ private void printNewLine( String message )
+ {
+ m_ioUtil.printNewLine( message );
+ }
+ }
+
+ /**
+ * Handler of ODA connection profile properties.
+ */
+ private static class OdaProfileHandler
+ {
+ private static final String SHORT_CUT_SYMBOL = "&"; //$NON-NLS-1$
+
+ private static boolean updateProfileProperties( IConnectionProfile profile, PropertyEditor propEditor )
+ {
+ ExtensionManifest odaManifest = getOdaManifest( profile );
+ if( odaManifest == null ) // no ODA manifest found
+ return updateRawProperties( profile, propEditor );
+
+ Properties profileProps = profile.getBaseProperties();
+
+ Property[] odaPropDefns = odaManifest.getProperties( false );
+ Properties propVisibility = odaManifest.getPropertiesVisibility();
+
+ boolean hasUpdates = false;
+ String newValue;
+ for( int i=0; i < odaPropDefns.length; i++ )
+ {
+ Property odaPropDefn = odaPropDefns[i];
+ if( ! odaPropDefn.isVisible( propVisibility ) || ! odaPropDefn.isEditable( propVisibility ) )
+ continue;
+
+ newValue = propEditor.promptNewPropertyValue( profileProps, odaPropDefn.getName(),
+ getPropertyDisplayName( odaPropDefn ),
+ odaPropDefn.isEncryptable() );
+ hasUpdates |= propEditor.setNewPropertyValue( profileProps, odaPropDefn.getName(), newValue );
+ }
+
+ // update the profile's properties
+ if( hasUpdates )
+ profile.setBaseProperties( profileProps );
+ return hasUpdates;
+ }
+
+ private static ExtensionManifest getOdaManifest( IConnectionProfile profile )
+ {
+ String odaDataSourceId = profile.getProviderId();
+ ExtensionManifest odaManifest = null;
+ try
+ {
+ odaManifest = ManifestExplorer.getInstance().getExtensionManifest( odaDataSourceId );
+ }
+ catch( Exception ex )
+ {
+ // ignore
+ }
+
+ return odaManifest;
+ }
+
+ private static String getPropertyDisplayName( Property odaPropDefn )
+ {
+ String displayName = odaPropDefn.getDisplayName();
+ // removes any short cut symbol embedded in the display name
+ return displayName.replaceAll( SHORT_CUT_SYMBOL, SystemIOUtil.EMPTY_STRING );
+ }
+
+ /**
+ * Update the profile properties without any property metadata available.
+ * All existing values are masked for display.
+ */
+ private static boolean updateRawProperties( IConnectionProfile profile, PropertyEditor propEditor )
+ {
+ Properties props = profile.getBaseProperties();
+ boolean hasUpdates = false;
+ propEditor.printNewLine( Messages.profileFile_noOdaPropertyDefn );
+
+ String newValue;
+ Iterator keysIter = props.keySet().iterator();
+ while( keysIter.hasNext() )
+ {
+ String propKey = (String) keysIter.next();
+ // since no property definition is available, use key as display name, and mask its existing value
+ newValue = propEditor.promptNewPropertyValue( props, propKey, propKey, true );
+ hasUpdates |= propEditor.setNewPropertyValue( props, propKey, newValue );
+ }
+
+ // update the profile's properties
+ if( hasUpdates )
+ profile.setBaseProperties( props );
+ return hasUpdates;
+ }
+ }
+
+ /**
+ * Handler of JDBC Database connection profile properties.
+ */
+ private static class DatabaseProfileHandler
+ {
+ private static final String PROPERTY_PAIR_SEPARATOR = ","; //$NON-NLS-1$
+ private static final String ASSIGNMENT_CHAR = "="; //$NON-NLS-1$
+
+ private static Map sm_dbPropKeys;
+
+ private static boolean updateProfileProperties( IConnectionProfile profile, PropertyEditor propEditor )
+ {
+ Properties profileProps = profile.getBaseProperties();
+ boolean hasUpdates = false;
+
+ // prompt to update each pre-defined database property key
+ Map dbPropKeys = getDbPropertyKeys();
+ String newValue;
+ Iterator entryIter = dbPropKeys.entrySet().iterator();
+ while( entryIter.hasNext() )
+ {
+ Map.Entry keyEntry = (Map.Entry) entryIter.next();
+ newValue = propEditor.promptNewPropertyValue( profileProps, (String) keyEntry.getKey(), (String) keyEntry.getValue() );
+ hasUpdates |= propEditor.setNewPropertyValue( profileProps, (String) keyEntry.getKey(), newValue );
+ }
+
+ // handle any additional name value pairs stored in connection profile
+ String nameValuePairs = profileProps .getProperty( IJDBCConnectionProfileConstants.CONNECTION_PROPERTIES_PROP_ID );
+ if( nameValuePairs != null && nameValuePairs.length() > 0)
+ {
+ String[] pairs = parseString( nameValuePairs, PROPERTY_PAIR_SEPARATOR );
+ for( int i = 0; i < pairs.length; i++ )
+ {
+ String[] namevalue = parseString( pairs[i], ASSIGNMENT_CHAR );
+ if( namevalue.length >= 2 )
+ {
+ newValue = propEditor.promptNewPropertyValue( namevalue[0], namevalue[1] );
+ hasUpdates |= propEditor.setNewPropertyValue( profileProps, namevalue[0], newValue );
+ }
+ }
+ }
+
+ // update the profile's properties
+ if( hasUpdates )
+ profile.setBaseProperties( profileProps );
+ return hasUpdates;
+ }
+
+ private static String[] parseString( String str_list, String token )
+ {
+ StringTokenizer tk = new StringTokenizer( str_list, token );
+ String[] pieces = new String[tk.countTokens()];
+ int index = 0;
+ while( tk.hasMoreTokens() )
+ pieces[index++] = tk.nextToken();
+ return pieces;
+ }
+
+ /**
+ * Returns a collection of Database property key and corresponding display name
+ * that are used to open a JDBC connection.
+ */
+ private static Map getDbPropertyKeys()
+ {
+ if( sm_dbPropKeys == null )
+ {
+ sm_dbPropKeys = new LinkedHashMap(5);
+ sm_dbPropKeys.put( IJDBCConnectionProfileConstants.URL_PROP_ID, Messages.profileFile_propertyUrl );
+ sm_dbPropKeys.put( IDriverMgmtConstants.PROP_DEFN_JARLIST,
+ Messages.bind( Messages.profileFile_propertyJarList, IDriverMgmtConstants.PATH_DELIMITER ) );
+ sm_dbPropKeys.put( IJDBCConnectionProfileConstants.DRIVER_CLASS_PROP_ID, Messages.profileFile_propertyDriverClass );
+ sm_dbPropKeys.put( IJDBCConnectionProfileConstants.USERNAME_PROP_ID, Messages.profileFile_propertyUser );
+ sm_dbPropKeys.put( IJDBCConnectionProfileConstants.PASSWORD_PROP_ID, Messages.profileFile_propertyPassword );
+ }
+ return sm_dbPropKeys;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/SystemIOUtil.java b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/SystemIOUtil.java
new file mode 100644
index 0000000..48ed4ee
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/internal/SystemIOUtil.java
@@ -0,0 +1,118 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2008 Actuate Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Actuate Corporation - initial API and implementation
+ *
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.console.profile.internal;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import org.eclipse.datatools.connectivity.console.profile.nls.Messages;
+
+/**
+ * Internal utility class to handle user interaction using system input and output.
+ */
+public class SystemIOUtil
+{
+ private static final String USER_CONFIRM_INPUT_CHAR = Messages.ioutil_confirmUserInputChar;
+ private static final String CONFIRM_PROMPT = // ['y' to confirm]
+ Messages.bind( " [''{0}'' {1}]", USER_CONFIRM_INPUT_CHAR, Messages.ioutil_confirmPromptInstruction ); //$NON-NLS-1$
+ private static final String INPUT_PROMPT_DELIMITER = ": "; //$NON-NLS-1$
+
+ static final String EMPTY_STRING = ""; //$NON-NLS-1$
+
+ private BufferedReader m_stdin;
+
+ SystemIOUtil() {}
+
+ String promptForInput( String promptMsg )
+ {
+ printInputPrompt( promptMsg + INPUT_PROMPT_DELIMITER );
+ return readLn();
+ }
+
+ boolean promptYesNoResponse( String promptMsg )
+ {
+ String response = promptForInput( promptMsg + CONFIRM_PROMPT );
+ return( response != null && response.equalsIgnoreCase( USER_CONFIRM_INPUT_CHAR ) );
+ }
+
+ /**
+ * Ask the user whether to update the existing value. If user confirms, ask for new input value.
+ * @return the new value entered by an user; or null if user does not want to change the current value
+ */
+ String promptForUpdateValue()
+ {
+ String newValue = null;
+ if( promptYesNoResponse( Messages.ioutil_askUpdateValue ) )
+ {
+ newValue = promptForInput( Messages.ioutil_newValuePrompt );
+ if( newValue == null )
+ newValue = EMPTY_STRING;
+ }
+ return newValue;
+ }
+
+ void printException( String errorMsg, Exception ex )
+ {
+ if( errorMsg != null )
+ println( errorMsg );
+ String exceptionMsg = ex.getLocalizedMessage();
+ if( exceptionMsg != null )
+ println( Messages.bind( Messages.ioutil_exceptionCause, exceptionMsg ));
+
+ if( promptYesNoResponse( Messages.ioutil_askReviewStack ))
+ ex.printStackTrace();
+ }
+
+ void printNewLine( String message )
+ {
+ printNewLine();
+ println( message );
+ }
+
+ void printNewLine()
+ {
+ System.out.println();
+ }
+
+ void println( String message )
+ {
+ System.out.println( message );
+ }
+
+ void printInputPrompt( String message )
+ {
+ System.out.print( message );
+ System.out.flush(); // empties buffer, before prompting for input text
+ }
+
+ String readLn()
+ {
+ if( m_stdin == null )
+ m_stdin = new BufferedReader( new InputStreamReader( System.in ) );
+
+ String message = null;
+ try
+ {
+ message = m_stdin.readLine();
+ }
+ catch( IOException ex )
+ {
+ printException( Messages.ioutil_errorSystemInput, ex );
+ }
+ return message;
+ }
+
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/nls/Messages.java b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/nls/Messages.java
new file mode 100644
index 0000000..49c7d20
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/nls/Messages.java
@@ -0,0 +1,82 @@
+/*
+ *************************************************************************
+ * Copyright (c) 2008 Actuate Corporation.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Actuate Corporation - initial API and implementation
+ *
+ *************************************************************************
+ */
+
+package org.eclipse.datatools.connectivity.console.profile.nls;
+
+import org.eclipse.osgi.util.NLS;
+
+public class Messages extends NLS
+{
+ private static final String BUNDLE_NAME = "org.eclipse.datatools.connectivity.console.profile.nls.messages"; //$NON-NLS-1$
+
+ public static String editorAppl_argKeyValue;
+ public static String editorAppl_promptEditProfileName;
+ public static String editorAppl_exitAppl;
+ public static String editorAppl_promptInputFile;
+ public static String editorAppl_invalidFileName;
+ public static String editorAppl_invalidInputFile;
+ public static String editorAppl_invalidOutputFile;
+ public static String editorAppl_missingArgValue;
+ public static String editorAppl_noProfileChanges;
+ public static String editorAppl_promptOutputFile;
+ public static String editorAppl_overwriteExistingFile;
+ public static String editorAppl_startAppl;
+ public static String editorAppl_syntaxArguments;
+
+ public static String editorAppl_syntaxCommand;
+ public static String editorAppl_syntaxHelpInstruction;
+ public static String editorAppl_syntaxInArgInstruction;
+ public static String editorAppl_syntaxNullArgInstruction;
+ public static String editorAppl_syntaxProfileNameInstruction2;
+ public static String editorAppl_syntaxOutArgInstruction;
+ public static String editorAppl_syntaxProfileNameInstruction1;
+ public static String editorAppl_syntaxUsage;
+ public static String ioutil_askReviewStack;
+ public static String ioutil_askUpdateValue;
+ public static String ioutil_confirmPromptInstruction;
+ public static String ioutil_errorSystemInput;
+ public static String ioutil_exceptionCause;
+ public static String ioutil_newValuePrompt;
+
+ public static String ioutil_confirmUserInputChar;
+ public static String profileFile_askEncryptOutput;
+ public static String profileFile_askUpdateProfile;
+ public static String profileFile_errorInstruction;
+ public static String profileFile_errorReadingFile;
+ public static String profileFile_errorSavingFile;
+ public static String profileFile_inputPromptDelimiter;
+ public static String profileFile_noOdaPropertyDefn;
+ public static String profileFile_noProfileFound;
+ public static String profileFile_propertyDriverClass;
+ public static String profileFile_propertyJarList;
+ public static String profileFile_propertyPassword;
+ public static String profileFile_profileIdentifier;
+ public static String profileFile_propertyUrl;
+ public static String profileFile_propertyUser;
+ public static String profileFile_specifiedProfileNotFound;
+ public static String profileFile_statusDone;
+ public static String profileFile_statusIteratingProfiles;
+ public static String profileFile_statusReadingFile;
+ public static String profileFile_statusSavingFile;
+
+ static
+ {
+ // initialize resource bundle
+ NLS.initializeMessages( BUNDLE_NAME, Messages.class );
+ }
+
+ private Messages()
+ {
+ }
+}
diff --git a/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/nls/messages.properties b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/nls/messages.properties
new file mode 100644
index 0000000..ced6af7
--- /dev/null
+++ b/plugins/org.eclipse.datatools.connectivity.console.profile/src/org/eclipse/datatools/connectivity/console/profile/nls/messages.properties
@@ -0,0 +1,61 @@
+#************************************************************************
+# Copyright (c) 2008 Actuate Corporation.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+# Actuate Corporation - initial API and implementation
+#
+#************************************************************************
+#
+editorAppl_argKeyValue={0} argument value: {1}
+editorAppl_exitAppl=The {0} application exited.
+editorAppl_invalidFileName=Invalid file name ({0}).
+editorAppl_invalidInputFile=The input file ({0}) does not exist or cannot be read.
+editorAppl_invalidOutputFile=The output file ({0}) is invalid or not writable.
+editorAppl_missingArgValue=Missing value for {0} argument.
+editorAppl_noProfileChanges=No changes were made to the connection profile(s).
+editorAppl_overwriteExistingFile=The output file ({0}) already exists. Overwrite its contents?
+editorAppl_promptEditProfileName=Enter the name of a connection profile to view/change (optional)
+editorAppl_promptInputFile=Enter the name of the connection profile file to view/change
+editorAppl_promptOutputFile=Enter the name of the output file to save your changes
+editorAppl_startAppl=Start the {0} application...
+editorAppl_syntaxArguments=Optional command line arguments:
+editorAppl_syntaxCommand=Use "eclipsec" in command on Windows, or "eclipse" on other platforms.
+editorAppl_syntaxHelpInstruction=displays this help message
+editorAppl_syntaxInArgInstruction=specifies the name of the connection profile storage file to view/change
+editorAppl_syntaxNullArgInstruction=If an argument value is not specified, the editor will prompt for an input value.
+editorAppl_syntaxOutArgInstruction=specifies the name of the output file to save your changes
+editorAppl_syntaxProfileNameInstruction1=specifies the name of a connection profile to view/change; if none is specified,
+editorAppl_syntaxProfileNameInstruction2=the tool will step through all the profiles found in the input file
+editorAppl_syntaxUsage=Command syntax:
+#
+ioutil_askReviewStack=Do you want to see the stack trace?
+ioutil_askUpdateValue=Update existing value?
+ioutil_confirmUserInputChar=y
+ioutil_confirmPromptInstruction=to confirm
+ioutil_errorSystemInput=Error in reading from input console.
+ioutil_exceptionCause=Exception was caused by: {0}
+ioutil_newValuePrompt=New value
+#
+profileFile_askEncryptOutput=Do you want to encrypt the output file?
+profileFile_askUpdateProfile=Update the profile's properties?
+profileFile_errorInstruction=Please see the workspace log for possible additional exceptions.
+profileFile_errorReadingFile=Error in reading the content of the profile input file.
+profileFile_errorSavingFile=Error in saving the updated properties to the output file.
+profileFile_inputPromptDelimiter=>>
+profileFile_noOdaPropertyDefn=Warning: Property definitions are not available. All existing property values will be masked.
+profileFile_noProfileFound=No profiles were found in the input file.
+profileFile_profileIdentifier={0} profile name
+profileFile_propertyDriverClass=JDBC Driver Class
+profileFile_propertyJarList=JDBC Driver Jar Paths (use ''{0}'' to separate paths)
+profileFile_propertyPassword=Password
+profileFile_propertyUrl=Connection URL
+profileFile_propertyUser=User name
+profileFile_specifiedProfileNotFound=The specified profile ({0}) is not found in the input file.
+profileFile_statusDone=Done.
+profileFile_statusIteratingProfiles=Stepping through each of the {0} profiles found in the input file...
+profileFile_statusReadingFile=Reading the input file ({0})...
+profileFile_statusSavingFile=Saving updated properties in the output file ({0})...