diff options
37 files changed, 2337 insertions, 1949 deletions
diff --git a/org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileLabelProvider.java b/org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileLabelProvider.java index 4bc18f588..7e3f0aeaa 100755 --- a/org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileLabelProvider.java +++ b/org.tizen.common.connection/src/org/tizen/common/connection/ui/TizenRemoteFileLabelProvider.java @@ -95,7 +95,7 @@ public class TizenRemoteFileLabelProvider implements ITableLabelProvider { { switch(index) { case 0: - return Integer.toString( entry.getSize() ); + return entry.getSize(); case 1: return entry.getDate(); case 2: diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/Device.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/Device.java index 73c53f7da..97c01e51e 100644 --- a/org.tizen.common.sdblib/src/org/tizen/sdblib/Device.java +++ b/org.tizen.common.sdblib/src/org/tizen/sdblib/Device.java @@ -236,7 +236,7 @@ implements IDevice FileEntry getRoot() { - return new FileEntry(this, null, getDeviceName(), isEmulator()?FileEntryType.RootEmulator:FileEntryType.RootDevice, null, null, null, 0, null, null, null, null ); + return new FileEntry(this, null, getDeviceName(), isEmulator()?FileEntryType.RootEmulator:FileEntryType.RootDevice, null, null, null, null, null, null, null, null ); } /* (non-Javadoc) @@ -266,7 +266,7 @@ implements IDevice } if ( ! bFound ) { - iter = new FileEntry( null, iter, fragment, FileEntryType.Unknown, null, null, null, 0, null, null, null, null ); + iter = new FileEntry( null, iter, fragment, FileEntryType.Unknown, null, null, null, null, null, null, null, null ); } } return iter; diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/FileEntryFactory.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/FileEntryFactory.java index bd9555098..b30292751 100644 --- a/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/FileEntryFactory.java +++ b/org.tizen.common.sdblib/src/org/tizen/sdblib/receiver/FileEntryFactory.java @@ -198,6 +198,6 @@ FileEntryFactory name = trimTrailingCharacter( name, '*' );
}
- return new FileEntry( null, parent, name, objectType, permissions, owner, group, parseInt( size, 0 ), date, time, info, linkTo );
+ return new FileEntry( null, parent, name, objectType, permissions, owner, group, size, date, time, info, linkTo );
}
}
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/service/CrashReportService.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/service/CrashReportService.java index fe341fb34..d454beb64 100644 --- a/org.tizen.common.sdblib/src/org/tizen/sdblib/service/CrashReportService.java +++ b/org.tizen.common.sdblib/src/org/tizen/sdblib/service/CrashReportService.java @@ -168,6 +168,11 @@ implements IDeviceChangeListener reply.flip(); notifyAllListeners( (IDevice) key.attachment(), UTF_CHARSET.decode( reply ).toString() ); } + else if ( len < 0 ) + { + key.cancel(); + tryClose( sc ); + } } catch ( final IOException e ) { @@ -322,6 +327,7 @@ implements IDeviceChangeListener while ( iter.hasNext() ) { final SelectionKey key = iter.next(); + Log.d( "crash", "Iteration: " + key.interestOps() ); if ( key.isConnectable() ) { final SocketChannel sc = (SocketChannel) key.channel(); diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/service/FileEntry.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/service/FileEntry.java index 226f44d28..dc427e173 100644 --- a/org.tizen.common.sdblib/src/org/tizen/sdblib/service/FileEntry.java +++ b/org.tizen.common.sdblib/src/org/tizen/sdblib/service/FileEntry.java @@ -125,7 +125,7 @@ implements Comparable<FileEntry> /**
* File size
*/
- protected final int size;
+ protected final String size;
/**
* File modified date
@@ -184,7 +184,7 @@ implements Comparable<FileEntry> final String permission,
final String owner,
final String group,
- final int size,
+ final String size,
final String date,
final String time,
final String info,
@@ -264,7 +264,7 @@ implements Comparable<FileEntry> * @return size of the entry
*/
public
- int
+ String
getSize()
{
return size;
diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/service/SyncService.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/service/SyncService.java index 86af582f7..493401949 100644 --- a/org.tizen.common.sdblib/src/org/tizen/sdblib/service/SyncService.java +++ b/org.tizen.common.sdblib/src/org/tizen/sdblib/service/SyncService.java @@ -434,7 +434,7 @@ implements Closeable * @param time out value while push the files * @return a {@link SyncResult} object with a code and an optional message. * - * @see #doPush(InputStream, FileEntry, ISyncProgressMonitor, int) + * @see #push(File[], FileEntry, ISyncProgressMonitor, int) */ public SyncResult @@ -455,17 +455,56 @@ implements Closeable monitor.startSubTask(MESSAGE_SIZECHECKING); + SyncResult result; + try { // get the total count of the bytes to transfer long total = getTotalLocalFileSizeLong( locals, monitor ); monitor.startSubTask( MESSAGE_PUSH_FILES ); monitor.stop(); + //start the monitor monitor.start( total ); + result = doPush(locals, remote, monitor, timeOut); + } + catch ( final InterruptedException e ) + { + return new SyncResult( RESULT_CANCELED ); + } + finally + { + monitor.stop(); + } + + return result; + } + + /** + * Push several files. + * @param locals An array of loca files to push + * @param remote the remote {@link FileEntry} representing a directory. + * @param monitor The progress monitor. Cannot be null. + * @param time out value while push the files + * @return a {@link SyncResult} object with a code and an optional message. + * + * @see #doPush(File[], FileEntry, ISyncProgressMonitor, int) + */ + public + SyncResult + doPush( + final File[] locals, + final FileEntry remote, + ISyncProgressMonitor monitor, + final int timeOut + ) + { + monitor = nvl( monitor, NullSyncProgressMonitor.getInstance() ); + + try { + final String remotePath = remote.getFullPath(); - - + for ( final File f : locals ) { // check if we're canceled @@ -475,7 +514,7 @@ implements Closeable if ( !f.exists() ) { - continue; + continue; } final String path = addTailingPath( remotePath, f.getName() ); @@ -484,27 +523,27 @@ implements Closeable monitor.startSubTask( String.format("%s\t%s", f.getAbsolutePath(), path ) ); if ( f.isDirectory() ) { - SyncResult result = push( f.listFiles(), remoteFile, monitor, timeOut); - - if (result.getCode() != RESULT_OK) - { - return result; - } + SyncResult result = doPush( f.listFiles(), remoteFile, monitor, timeOut); + + if (result.getCode() != RESULT_OK) + { + return result; + } } - else if (f.isFile() ) + else if ( f.isFile() ) { - FileInputStream fileIn = new FileInputStream( f ); - try - { - SyncResult result = doPush( fileIn, remoteFile, monitor, timeOut); - if (result.getCode() != RESULT_OK) { - return result; - } - } - finally - { - tryClose( fileIn ); - } + FileInputStream fileIn = new FileInputStream( f ); + try + { + SyncResult result = doPush( fileIn, remoteFile, monitor, timeOut); + if (result.getCode() != RESULT_OK) { + return result; + } + } + finally + { + tryClose( fileIn ); + } } } @@ -512,17 +551,8 @@ implements Closeable } catch ( final IOException e ) { - return new SyncResult( RESULT_FILE_READ_ERROR ); - } - catch ( final InterruptedException e ) - { - return new SyncResult(RESULT_CANCELED); + return new SyncResult( RESULT_FILE_READ_ERROR, e ); } - finally - { - monitor.stop(); - } - } /** diff --git a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/FileEntryUtil.java b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/FileEntryUtil.java index 9302f1609..4a415b246 100644 --- a/org.tizen.common.sdblib/src/org/tizen/sdblib/util/FileEntryUtil.java +++ b/org.tizen.common.sdblib/src/org/tizen/sdblib/util/FileEntryUtil.java @@ -70,7 +70,7 @@ FileEntryUtil }
else if (type == FileEntryType.File)
{
- count += e.getSize();
+ count += ParsingUtil.parseLong( e.getSize(), 0 );
}
}
diff --git a/org.tizen.common.sign/.classpath b/org.tizen.common.sign/.classpath index 575478c5f..7589ba486 100644 --- a/org.tizen.common.sign/.classpath +++ b/org.tizen.common.sign/.classpath @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> + <classpathentry exported="true" kind="lib" path="lib/KeyCertGeneratorApi.jar"/> <classpathentry exported="true" kind="lib" path="lib/commons-codec-1.4.jar"/> <classpathentry exported="true" kind="lib" path="lib/HashSign.jar"/> <classpathentry exported="true" kind="lib" path="lib/xmlsec-1.5.3.jar"/> diff --git a/org.tizen.common.sign/META-INF/MANIFEST.MF b/org.tizen.common.sign/META-INF/MANIFEST.MF index c30b2adef..fc402fef2 100644 --- a/org.tizen.common.sign/META-INF/MANIFEST.MF +++ b/org.tizen.common.sign/META-INF/MANIFEST.MF @@ -21,8 +21,9 @@ Export-Package: hashsign, org.tizen.common.sign.signer, org.tizen.common.sign.ui, org.tizen.common.sign.util -Bundle-ClassPath: lib/CertificateGenerator.jar, - ., +Bundle-ClassPath: lib/KeyCertGeneratorApi.jar, + lib/CertificateGenerator.jar, lib/HashSign.jar, lib/xmlsec-1.5.3.jar, - lib/commons-codec-1.4.jar + lib/commons-codec-1.4.jar, + . diff --git a/org.tizen.common.sign/OSGI-INF/l10n/bundle.properties b/org.tizen.common.sign/OSGI-INF/l10n/bundle.properties index 4b038856d..c6366b73a 100644 --- a/org.tizen.common.sign/OSGI-INF/l10n/bundle.properties +++ b/org.tizen.common.sign/OSGI-INF/l10n/bundle.properties @@ -1,4 +1,4 @@ #Properties file for org.tizen.common.sign Bundle-Vendor = The Linux Foundation Bundle-Name = Tizen Common Sign -page.name = Secure Profiles
\ No newline at end of file +page.name = Security Profiles
\ No newline at end of file diff --git a/org.tizen.common.sign/build.properties b/org.tizen.common.sign/build.properties index 95c3a8588..18f9a37b8 100644 --- a/org.tizen.common.sign/build.properties +++ b/org.tizen.common.sign/build.properties @@ -10,4 +10,5 @@ bin.includes = plugin.xml,\ lib/xmlsec-1.5.3.jar,\ about_files/,\ about.html,\ - lib/commons-codec-1.4.jar + lib/commons-codec-1.4.jar,\ + lib/KeyCertGeneratorApi.jar diff --git a/org.tizen.common.sign/certificates/developer/conf.ini b/org.tizen.common.sign/certificates/developer/conf.ini new file mode 100644 index 000000000..fe782eaff --- /dev/null +++ b/org.tizen.common.sign/certificates/developer/conf.ini @@ -0,0 +1 @@ +PASSWD_OF_ISSUER_FOR_DEV=tizencertificatefordevelopercaroqkfwk diff --git a/org.tizen.common.sign/certificates/developer/tizen-developer-ca-privatekey.pem b/org.tizen.common.sign/certificates/developer/tizen-developer-ca-privatekey.pem new file mode 100644 index 000000000..47e13555e --- /dev/null +++ b/org.tizen.common.sign/certificates/developer/tizen-developer-ca-privatekey.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-128-CBC,231BF253A4AA10E1F1A450D5AB3385F2 + +McTL9+jm/Fuu3pHC6zm/epNhCqgSXswlZVc59zi9Rx+9SSOCNjHm2VChPsWmTU7G +Q4Fwerq/95/s5B2/nnO9LXgn/hMZbsFtva3awzcSDWLImwvBmn9Kzc9wym3G4GC0 +cpDzT3/i+EdR1qLLfLiEZ81sHWbEui1ywtraJMfhmz07rwLTQ7UrXT63YdsgbRUN +sk/ESxgc223Dc9SbPF94lwmOeDQTbM3hIuNmizUJTPVzQGGARFqiXiPjjechJ7NS +0ds8M7Bb3tF+blyTZmS53ymBE30PXwnWuZ2nv1eC05E0jK/XwgSqTY0hekMeGcB7 +b07eELzcyEtovG1N+F+vDkEdZkhhjui7OgPoXMPZfuv+Bi8LK1lpsbiSz/BRNTP0 +6QKsJy0xxKSlGjsX3lA+XpXi/jfDW0yaxubpzNPM5XW0vhuNcyK/rUw0KKQCD3DO +rjoe67RUJYfQKEVgsmJEo69Hf1Jbk7kShP72FehEQ/fMONZMULTEleWY1tchOeEd +QNXElFqXCiCvTw2rMT/mLDuhXolv6M/mmV4A/L1RboBpsG8wSKJ+4cavtXDMll3o +5dMKrXqkCzKajZFASgVcr7CW2XJQjTpx2/bolc+4K4WyUJ+IcrqF+8igfmiDCzic +LhDOsYhiyNcw8fmW95tudH+9tg4IGbA3R6VZFejM8vxvNmO1lNXruiNVVcrvLUSk +k65JAkWn12rV/P4eCBsg9b/dNV7GKydxO4B1a7gindC950sjwc6X+0+waysbp7zk +QUOaDGBJGgSQe0UL55oRHqUe2t7ZM7rmqdxsApwH5xDGnPRQQ0zecA6t6AmrDmAH +-----END RSA PRIVATE KEY----- diff --git a/org.tizen.common.sign/certificates/developer/tizen-developer-ca.cer b/org.tizen.common.sign/certificates/developer/tizen-developer-ca.cer new file mode 100644 index 000000000..780396974 --- /dev/null +++ b/org.tizen.common.sign/certificates/developer/tizen-developer-ca.cer @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICpzCCAhCgAwIBAgIJAKzDjmEF+1OXMA0GCSqGSIb3DQEBBQUAMIGTMQswCQYD +VQQGEwJLUjEOMAwGA1UECAwFU3V3b24xDjAMBgNVBAcMBVN1d29uMRYwFAYDVQQK +DA1UaXplbiBUZXN0IENBMSUwIwYDVQQLDBxUaXplbiBUZXN0IERldmVsb3BlciBS +b290IENBMSUwIwYDVQQDDBxUaXplbiBUZXN0IERldmVsb3BlciBSb290IENBMB4X +DTEyMTAyOTEzMDEyMloXDTIyMTAyNzEzMDEyMlowgYQxCzAJBgNVBAYTAktSMQ4w +DAYDVQQIDAVTdXdvbjEOMAwGA1UEBwwFU3V3b24xFjAUBgNVBAoMDVRpemVuIFRl +c3QgQ0ExIDAeBgNVBAsMF1RpemVuIERldmVsb3BlciBUZXN0IENBMRswGQYDVQQD +DBJUaXplbiBEZXZlbG9wZXIgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB +AMyG0DSTHBgalQo1seDKxpCU61gji+QQlxQkPQOvBrmuF6Z90zFCprTtg2sRjTLC +NoRd75+VCCHuKGcrD27t7hwAekusPrpzdsq5QoBMvNjGDM22lC45PJ4d86DEDY4e +rxeJ5aSQxqbfXK4pKe9NwxdkKuA8dTYZM1UcmhXs7YALAgMBAAGjEDAOMAwGA1Ud +EwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEACbr/OPNMJ+Ejrxfm/YjCiRPpjJLn +wXS2IDtitbxot6bEdZkZvOFXOC0Ca4GT+jtvOcSlU7tM3Mdd1MrKe1kkoVd1vhCV +8V4CK3/DPj8aN3rxfMfQitA6XMDcxzhsyMWz56OdifX50dvS/G/ad+kGhNhOOEKS +E8zUyEDCGwqkfXk= +-----END CERTIFICATE----- diff --git a/org.tizen.common.sign/lib/KeyCertGeneratorApi.jar b/org.tizen.common.sign/lib/KeyCertGeneratorApi.jar Binary files differnew file mode 100644 index 000000000..5b3b82e8a --- /dev/null +++ b/org.tizen.common.sign/lib/KeyCertGeneratorApi.jar diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/command/ReadSigningProfileFileCommand.java b/org.tizen.common.sign/src/org/tizen/common/sign/command/ReadSigningProfileFileCommand.java index 658520ebe..4ecefcd09 100755 --- a/org.tizen.common.sign/src/org/tizen/common/sign/command/ReadSigningProfileFileCommand.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/command/ReadSigningProfileFileCommand.java @@ -29,6 +29,7 @@ import static org.tizen.common.util.IOUtil.tryClose; import hashsign.HashingSigning; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; @@ -53,9 +54,10 @@ import org.tizen.common.file.FileHandler.Attribute; import org.tizen.common.file.FileHandler.Type; import org.tizen.common.sign.exception.CertificationException; import org.tizen.common.sign.model.SignatureConstants; +import org.tizen.common.sign.preferences.SigningProfile; +import org.tizen.common.sign.preferences.SigningProfileContainer; import org.tizen.common.sign.preferences.SigningProfileItem; -import org.tizen.common.sign.util.SigningProfileUtil; -import org.tizen.common.util.IOUtil; +import org.tizen.common.util.Assert; import org.tizen.common.util.StringUtil; public class @@ -68,12 +70,14 @@ extends AbstractCommand<Object> protected final String profileName; - protected InputStream profileInputStream; - - protected List<SigningProfileItem> profileItems = new ArrayList<SigningProfileItem>(); - + protected SigningProfileContainer container; + + public ReadSigningProfileFileCommand( final String path, final String profileName ) { + Assert.notNull( path ); + Assert.notNull( profileName ); + this.path = path; this.profileName = profileName; @@ -86,24 +90,22 @@ extends AbstractCommand<Object> ) throws Exception { - if ( !canRun( context ) ) - { + if ( ! canRun( context ) ) { return ; } final FileHandler fileHandler = context.getFileHandler(); - byte[] bytes = IOUtil.getBytes( fileHandler.read( this.path ) , true); - this.profileInputStream = new ByteArrayInputStream( bytes ); + InputStream profileInputStream = fileHandler.read( this.path ); try { - this.profileItems = SigningProfileUtil.parseProfileFile( this.profileInputStream, this.profileName ); + this.container = new SigningProfileContainer(); + this.container.readProfileXML( profileInputStream ); interactForPassword( executor, context ); validateSigningInfo(); } finally { - tryClose( this.profileInputStream ); - this.profileInputStream = null; + tryClose( profileInputStream ); } } @@ -138,128 +140,151 @@ extends AbstractCommand<Object> } } - /* + /** * validate password, if inputed wrong password then throw CertificationException */ protected void validateSigningInfo() throws CertificationException { - SigningProfileItem authorItem = getItem( true ); - SigningProfileItem distributorItem = getItem( false ); - - boolean hasAuthor = isValidItem( authorItem ); - boolean hasDistributor = isValidItem( distributorItem ); - - if ( hasAuthor ) { - // author password validating - checkPkcs12Password( authorItem ); + SigningProfile profile = getProfile(); + if ( profile == null ) { + return; } - - if ( hasDistributor ) { - // distributor password validating - checkPkcs12Password( distributorItem ); + + for (SigningProfileItem item : profile.getProfileItems() ) { + if ( isValidItem( item ) ) { + checkPkcs12Password( item ); + } } } protected void interactForPassword(final Executor executor, final ExecutionContext context) throws Exception { - SigningProfileItem authorItem = getItem( true ); - SigningProfileItem distributorItem = getItem( false ); - + // get specified profile + SigningProfile profile = getProfile(); + if ( profile == null ) { + return; + } + + // get required profile items. + SigningProfileItem authorItem = profile.getProfileItem( SigningProfile.AUTHOR_ORDINAL ); boolean hasAuthor = isValidItem( authorItem ); - boolean hasDistributor = isValidItem( distributorItem ); - if ( !hasAuthor ) { + SigningProfileItem dist1Item = profile.getProfileItem( 1 ); + boolean hasDist1 = isValidItem( dist1Item ); + + if ( ! hasAuthor || ! hasDist1 ) { // If don't have author certificate, no interact. return; } - if ( ! authorItem.hasPassword() || - ( hasDistributor && ! distributorItem.hasPassword() ) ) { - - ArrayList<UserField> fieldList = new ArrayList<UserField>(); - - // Author password text - UserField authorText = new UserField( SignatureConstants.AUTHOR, "Author password : ", char[].class ); - authorText.setValue( authorItem.getPassword() ); - authorText.setValidator( new InputValidator() { + // get an optional profile item + SigningProfileItem dist2Item = profile.getProfileItem( 2 ); + boolean hasDist2 = isValidItem( dist2Item ); + + // If not need to input password, skip + if ( authorItem.hasPassword() && dist1Item.hasPassword() && + ( !hasDist2 || dist2Item.hasPassword() ) ) { + return; + } + + // generate fields + List<UserField> fieldList = new ArrayList<UserField>(); + Object[][] fields = new Object[][] { + new Object[] { SignatureConstants.AUTHOR, "Author password: ", true, authorItem.getPassword(), "Input author password.", "authorPwdSavable", "Save author password" }, + new Object[] { SignatureConstants.DISTRIBUTOR_1ST, "Distributor1 password: ", true, dist1Item.getPassword(), "Input distributor1 password.", "dist1PwdSavable", "Save distributor1 password" }, + new Object[] { SignatureConstants.DISTRIBUTOR_2ND, "Distributor2 password: ", hasDist2, dist2Item.getPassword(), "Input distributor2 password.", "dist2PwdSavable", "Save distributor2 password" }, + }; + for (Object[] field : fields ) { + final String textId = (String) field[0]; + final String textMsg = (String) field[1]; + final boolean modifiable = (Boolean) field[2]; + final char[] password = (char[]) field[3]; + final String validatorMsg = (String) field[4]; + final String buttonId = (String) field[5]; + final String buttonMsg = (String) field[6]; + + UserField textField = createPasswordField( textId, textMsg, modifiable, password, validatorMsg ); + fieldList.add( textField ); + + UserField buttonField = createButtonField( buttonId, buttonMsg, modifiable ); + fieldList.add( buttonField ); + } + + // options + Map<String, Object> options = new HashMap<String, Object>(); + options.put( PrompterConstants.OPTION_TITLE, "Signing Dialog" ); // title + + // Interact passwords + context.getPrompter().batch( fieldList, options ); + + // write savable profile items + boolean[] updateFlags = { true, true, hasDist2 }; + for ( int i = SigningProfile.AUTHOR_ORDINAL; i <= SigningProfile.MAX_DISTRIBUTOR; i++ ) { + updateProfileItem( profile, i, fieldList.get( i * 2 ), fieldList.get( i * 2 + 1), updateFlags[ i ], true ); + } + writeProfiles( executor, context ); + + // synchronize unsavable profile items + for ( int i = SigningProfile.AUTHOR_ORDINAL; i <= SigningProfile.MAX_DISTRIBUTOR; i++ ) { + updateProfileItem( profile, i, fieldList.get( i * 2 ), fieldList.get( i * 2 + 1), updateFlags[ i ], false ); + } + } + + protected void updateProfileItem(SigningProfile profile, int ordinal, UserField text, UserField button, boolean modifiable, boolean savable) { + boolean saveValue = getBoolean( button.getValue() ); + if ( ! savable ) { + saveValue = ! saveValue; + } + + if ( modifiable && saveValue ) { + SigningProfileItem profileItem = profile.removeProfileItem( ordinal ); + profileItem.setPassword( (char[]) text.getValue() ); + profile.setProfileItem( ordinal, profileItem ); + } + } + + protected UserField createPasswordField(String id, String message,boolean modifiable, char[] password, final String validatorMsg) { + UserField userField = new UserField( id, message, char[].class ); + if ( ! modifiable ) { + userField.setModify( false ); + } else { + userField.setValue( password ); + userField.setValidator( new InputValidator() { @Override public String check(Object value) { if ( value instanceof String ) { - return StringUtil.isEmpty( (String) value ) ? "Input author password." : null; + return StringUtil.isEmpty( (String) value ) ? validatorMsg : null; } return null; } } ); - fieldList.add( authorText ); - - // Savable author password button - UserField authorButton = new UserField( "authorPwdSavable", "Save author password", boolean.class ); - fieldList.add( authorButton ); - - // Distributor password text - UserField distributor2Text = new UserField( SignatureConstants.DISTRIBUTOR_2ND, "Distributor password : ", char[].class ); - if ( !hasDistributor ) { - distributor2Text.setModify( false ); - } else { - distributor2Text.setValue( distributorItem.getPassword() ); - distributor2Text.setValidator( new InputValidator() { - @Override - public String check(Object value) { - if ( value instanceof String ) { - return StringUtil.isEmpty( (String) value ) ? "Input distributor password." : null; - } - return null; - } - } ); - } - fieldList.add( distributor2Text ); - - // Savable distributor2 password button - UserField distributor2Button = new UserField( "distributorPwdSavable", "Save distributor password", boolean.class ); - if ( !hasDistributor ) { - distributor2Button.setModify( false ); - } - fieldList.add( distributor2Button ); - - // options - Map<String, Object> options = new HashMap<String, Object>(); - options.put( PrompterConstants.OPTION_TITLE, "Signing Dialog" ); // title - - // Interact passwords - context.getPrompter().batch( fieldList, options ); - - // save profiles - boolean saveAuthor = getBoolean( authorButton.getValue() ); - boolean saveDistributor = hasDistributor ? getBoolean( distributor2Button.getValue() ) : false; - - if ( saveAuthor ) { - authorItem.setPassword( (char[]) authorText.getValue() ); - } - if ( hasDistributor && saveDistributor ) { - distributorItem.setPassword( (char[]) distributor2Text.getValue() ); - } - - writeProfiles( executor, context ); - - // synchronize profile password - if ( !saveAuthor ) { - authorItem.setPassword( (char[]) authorText.getValue() ); - } - if ( hasDistributor && !saveDistributor ) { - distributorItem.setPassword( (char[]) distributor2Text.getValue() ); - } } + + return userField; + } + + protected UserField createButtonField(String id, String message, boolean modifiable ) { + UserField userField = new UserField( id, message, boolean.class ); + if ( ! modifiable ) { + userField.setModify( false ); + } + + return userField; + } + + public SigningProfile getProfile() { + if ( this.container == null || this.profileName == null ) { + return null; + } + return this.container.getProfileByName( this.profileName ); } protected void writeProfiles(final Executor executor, final ExecutionContext context) throws Exception { final FileHandler fileHandler = context.getFileHandler(); - this.profileInputStream.reset(); - final InputStream in = SigningProfileUtil.updateProfiles( this.profileInputStream, this.profileName, this.profileItems ); - if ( in == null ) { - logger.warn( "Cannot update profiles" ); - return; - } + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + this.container.writeProfileXML( outStream ); + InputStream in = new ByteArrayInputStream( outStream.toByteArray() ); try { fileHandler.write( this.path, in ); @@ -286,26 +311,11 @@ extends AbstractCommand<Object> } return ( Type.FILE.equals( fileHandler.get( path, Attribute.TYPE ) ) ); } - - public List<SigningProfileItem> getProfileItems() - { - return this.profileItems; - } - + protected boolean isValidItem(SigningProfileItem item) { return item == null ? false : item.hasKeyLocation(); } - protected SigningProfileItem getItem(boolean author) { - for ( SigningProfileItem item : this.profileItems ) { - if ( item.isAuthor() == author ) { - return item; - } - } - - return null; - } - protected boolean getBoolean(Object obj) { return ( obj == null ) ? true : Boolean.parseBoolean( String.valueOf( obj ) ); } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/command/SignCommand.java b/org.tizen.common.sign/src/org/tizen/common/sign/command/SignCommand.java index 168ef9dbe..39ce1a2f0 100755 --- a/org.tizen.common.sign/src/org/tizen/common/sign/command/SignCommand.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/command/SignCommand.java @@ -25,7 +25,6 @@ package org.tizen.common.sign.command; import java.io.IOException; -import java.util.List; import org.apache.commons.lang3.time.StopWatch; import org.tizen.common.core.command.ExecutionContext; @@ -37,6 +36,7 @@ import org.tizen.common.file.FileHandler; import org.tizen.common.file.FileHandler.Attribute; import org.tizen.common.file.FileHandler.Type; import org.tizen.common.sign.exception.CertificationException; +import org.tizen.common.sign.preferences.SigningProfile; import org.tizen.common.sign.preferences.SigningProfileItem; import org.tizen.common.sign.signer.TizenSigner; import org.tizen.common.sign.util.SignatureUtility; @@ -46,35 +46,22 @@ import org.tizen.common.util.StringUtil; public class SignCommand extends FileHandlingCommand<Object> { - // active profile name - protected String profileName; - - protected List<SigningProfileItem> profileItems; - - // categorized profiles - protected SigningProfileItem authorProfile = null; - protected SigningProfileItem distributor1Profile = null; - protected SigningProfileItem distributor2Profile = null; + protected SigningProfile profile; protected boolean bRDS; // Constructor - public SignCommand(final String root, final String profileName, final List<SigningProfileItem> profileItems) { - this( root, profileName, profileItems, false ); + public SignCommand(final String root, final SigningProfile profile) { + this( root, profile, false ); } - public SignCommand(final String root, final String profileName, final List<SigningProfileItem> profileItems, boolean bRDS) { + public SignCommand(final String root, final SigningProfile profile, boolean bRDS) { this.path = root; - this.profileName = profileName; - this.profileItems = profileItems; + this.profile = profile; this.bRDS = bRDS; } - protected String getActiveProfileName() { - return this.profileName; - } - public void run(final Executor executor, final ExecutionContext context) throws IOException, CertificationException { final FileHandler handler = context.getFileHandler(); Assert.notNull( handler ); @@ -89,9 +76,6 @@ public class SignCommand extends FileHandlingCommand<Object> { final String appDirPath = (String) handler.get( this.path, Attribute.PATH ); - // categorize profile - categorizeProfiles(); - // remove old signatures for ( String child : handler.list( appDirPath ) ) { Object type = handler.get( child, Attribute.TYPE ); @@ -113,17 +97,18 @@ public class SignCommand extends FileHandlingCommand<Object> { stopWatch.start(); // If option for launch is false, must have author profile. - if ( this.authorProfile != null ) { - signAuthor( appDirPath, this.authorProfile ); - signDistributor1( appDirPath, this.distributor1Profile ); - if ( this.distributor2Profile != null ) { - signDistributor2( appDirPath, this.distributor2Profile ); + SigningProfileItem authorItem = this.profile.getProfileItem( SigningProfile.AUTHOR_ORDINAL ); + SigningProfileItem dist1Item = this.profile.getProfileItem( 1 ); + SigningProfileItem dist2Item = this.profile.getProfileItem( 2 ); + + if ( authorItem != null && dist1Item != null ) { + signAuthor( appDirPath, authorItem ); + signDistributor1( appDirPath, dist1Item ); + if ( dist2Item != null ) { + signDistributor2( appDirPath, dist2Item ); } - } else if ( this.distributor1Profile != null ) { - // sign developer profile only, no check - signDistributor1( appDirPath, this.distributor1Profile ); } else { - logger.error( "Profiles is not set. Author : {}, Dist1 : {}", this.authorProfile, this.distributor1Profile ); + logger.error( "Profiles is not set. Author : {}, Dist1 : {}", authorItem, dist1Item ); } } catch (Exception e) { context.getPrompter().error( e.getMessage() ); @@ -136,22 +121,6 @@ public class SignCommand extends FileHandlingCommand<Object> { } } - private void categorizeProfiles() { - for ( SigningProfileItem profileItem : this.profileItems ) { - if ( !StringUtil.isEmpty( profileItem.getKeyLocation() ) ) { - if ( profileItem.isAuthor() && this.authorProfile == null ) { - this.authorProfile = profileItem; - } else if ( this.distributor1Profile == null ) { - this.distributor1Profile = profileItem; - } else if ( this.distributor2Profile == null ) { - this.distributor2Profile = profileItem; - } else { - break; - } - } - } - } - private void signAuthor(String appDirPath, SigningProfileItem profileItem) throws Exception { if ( this.bRDS ) { TizenSigner.authorIncrementalSign( appDirPath, diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/model/SignatureConstants.java b/org.tizen.common.sign/src/org/tizen/common/sign/model/SignatureConstants.java index ab33600e7..cd431acb3 100755 --- a/org.tizen.common.sign/src/org/tizen/common/sign/model/SignatureConstants.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/model/SignatureConstants.java @@ -28,11 +28,29 @@ package org.tizen.common.sign.model; public interface SignatureConstants { - String AUTHOR = "author"; - String DISTRIBUTOR = "distributor"; - String DISTRIBUTOR_1ST = DISTRIBUTOR + "1"; - String DISTRIBUTOR_2ND = DISTRIBUTOR + "2"; + public static final String AUTHOR = "author"; + public static final String DISTRIBUTOR = "distributor"; + public static final String DISTRIBUTOR_1ST = DISTRIBUTOR + "1"; + public static final String DISTRIBUTOR_2ND = DISTRIBUTOR + "2"; public static final String SIGNATURE_META_FILE = ".manifest.tmp"; + // for preference store + public static final String DEFAULT_PROFILE_KEY = "defaultprofile"; + + public static final String PROFILES_FILE = "profiles.xml"; + + // for XML parser + public static final String ROOT_ELEMENT = "profiles"; + public static final String ROOT_ATTR_VER = "version"; + public static final String PROFILE_ELEMENT = "profile"; + public static final String PROFILE_ATTR_NAME = "name"; + public static final String PROFILEITEM_ELEMENT = "profileitem"; + public static final String PROFILEITEM_ATTR_KEY = "key"; + public static final String PROFILEITEM_ATTR_AUTHOR = "author"; + public static final String PROFILEITEM_ATTR_DISTRIBUTOR = "distributor"; + public static final String PROFILEITEM_ATTR_CA = "ca"; + public static final String PROFILEITEM_ATTR_ROOTCA = "rootca"; + public static final String PROFILEITEM_ATTR_PASS = "password"; + } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/Messages.properties b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/Messages.properties index 4ddde00a6..eee995393 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/Messages.properties +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/Messages.properties @@ -3,8 +3,8 @@ AUTOINSERT_BTN=Insert signature at launching PROFILES_COLUMN1=Certificate path PROFILES_COLUMN2=Password -PROFILES_COLUMN3=CA path(Optional) -PROFILES_COLUMN4=Root CA path(Optional) +PROFILES_COLUMN3=CA path (Optional) +PROFILES_COLUMN4=Root CA path (Optional) PROFILES_ADD_BTN=Add PROFILES_ADD_TOOLTIP=Add Profile diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileCellModifier.java b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileCellModifier.java index 0c0a9ee9a..442d00e53 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileCellModifier.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileCellModifier.java @@ -29,65 +29,68 @@ package org.tizen.common.sign.preferences; import org.eclipse.jface.viewers.ICellModifier; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.widgets.TableItem; -import org.tizen.common.sign.util.SigningProfileUtil; +import org.tizen.common.sign.model.SignatureConstants; + public class ProfileCellModifier implements ICellModifier { - private TableViewer viewer; - private SigningPreferencePage page; - + private TableViewer viewer; + private SigningPreferencePage page; + - public ProfileCellModifier(TableViewer viewer, SigningPreferencePage signingPreferencePage) { - this.viewer = viewer; - this.page = signingPreferencePage; - } - - @Override - public boolean canModify(Object element, String property) { - return true; - } + public ProfileCellModifier(TableViewer viewer, SigningPreferencePage signingPreferencePage) { + this.viewer = viewer; + this.page = signingPreferencePage; + } + + @Override + public boolean canModify(Object element, String property) { + return false; + } - @Override - public Object getValue(Object element, String property) { - - if (element instanceof SigningProfileItem) { - if (property.equals(SigningProfileUtil.ITEM_ATTR_PASS)) { - return ((SigningProfileItem)element).getPassword(); - } else if (property.equals(SigningProfileUtil.ITEM_ATTR_KEY)) { - return ((SigningProfileItem)element).getKeyLocation(); - } - else if (property.equals(SigningProfileUtil.ITEM_ATTR_CA)) { - return ((SigningProfileItem)element).getCAPath(); - } - else if (property.equals(SigningProfileUtil.ITEM_ATTR_ROOTCA)) { - return ((SigningProfileItem)element).getRootCAPath(); + @Override + public Object getValue(Object element, String property) { + if ( element instanceof SigningProfileItem ) { + SigningProfileItem item = (SigningProfileItem) element; + + if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_PASS ) ) { + return item.getPassword(); + } else if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_KEY ) ) { + return item.getKeyLocation(); + } else if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_CA ) ) { + return item.getCAPath(); + } else if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_ROOTCA ) ) { + return item.getRootCAPath(); } - } - return null; - } + } + + return null; + } - @Override - public void modify(Object element, String property, Object value) { - if (element instanceof TableItem) { - Object data = ((TableItem)element).getData(); - SigningProfileItem profileItem = (SigningProfileItem)data; - String _value = (String) value; - if (data instanceof SigningProfileItem) { - if (property.equals(SigningProfileUtil.ITEM_ATTR_PASS)) { - profileItem.setPassword(_value.toCharArray()); - } - else if (property.equals(SigningProfileUtil.ITEM_ATTR_KEY)) { - profileItem.setKeyLocation(_value); - } - else if(property.equals(SigningProfileUtil.ITEM_ATTR_CA)) { - profileItem.setCAPath(_value); - } - else if(property.equals(SigningProfileUtil.ITEM_ATTR_ROOTCA)) { - profileItem.setRootCAPath(_value); - } - } - viewer.update(data, null); - page.validatePreferencePage(); - } - } + @Override + public void modify(Object element, String property, Object value) { + Object data = null; + + if ( element instanceof TableItem ) { + data = ((TableItem) element).getData(); + } + + if ( data instanceof SigningProfileItem ) { + SigningProfileItem item = (SigningProfileItem) data; + String _value = (String) value; + + if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_PASS ) ) { + item.setPassword( _value.toCharArray() ); + } else if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_KEY ) ) { + item.setKeyLocation( _value ); + } else if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_CA ) ) { + item.setCAPath( _value ); + } else if ( property.equals( SignatureConstants.PROFILEITEM_ATTR_ROOTCA ) ) { + item.setRootCAPath( _value ); + } + + viewer.update( data, null ); + page.validatePreferencePage(); + } + } } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemContentProvider.java b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemContentProvider.java index 40251b8c7..898f6244a 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemContentProvider.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemContentProvider.java @@ -26,28 +26,26 @@ package org.tizen.common.sign.preferences; -import java.util.List; - import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.Viewer; public class ProfileItemContentProvider implements IStructuredContentProvider { - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof SigningProfile) { - List<SigningProfileItem> profileItemList = ((SigningProfile)inputElement).getProfileItemList(); - return profileItemList.toArray(); - } - return null; - } + + @Override + public Object[] getElements(Object inputElement) { + if ( inputElement instanceof SigningProfileItem[] ) { + return (SigningProfileItem[]) inputElement; + } + + return null; + } - @Override - public void dispose() { - } + @Override + public void dispose() { + } - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemLabelProvider.java b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemLabelProvider.java index b8e545b58..c9a0acb32 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemLabelProvider.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/ProfileItemLabelProvider.java @@ -36,40 +36,42 @@ extends LabelProvider implements ITableLabelProvider { - @Override - public Image getColumnImage(Object element, int columnIndex) { - return null; - } + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } - @Override - public String getColumnText(Object element, int columnIndex) { - if (columnIndex == 0) { - if (element instanceof SigningProfileItem) { - return ((SigningProfileItem)element).getKeyLocation(); - } - } else if (columnIndex == 1) { - if (element instanceof SigningProfileItem) { - char[] identifier = ((SigningProfileItem)element).getPassword(); - if(identifier == null) { - return null; - } - int passLength = identifier.length; - StringBuffer result = new StringBuffer(); - for(int i=0; i<passLength; i++) { - result.append("*"); - } - return result.toString(); - } - } else if (columnIndex == 2) { - if(element instanceof SigningProfileItem) { - return ((SigningProfileItem)element).getCAPath(); - } - } else if(columnIndex == 3) { - if(element instanceof SigningProfileItem) { - return ((SigningProfileItem)element).getRootCAPath(); - } - } - return Messages.ELEMENT_NOT_FOUND; - } + @Override + public String getColumnText(Object element, int columnIndex) { + if ( element instanceof SigningProfileItem ) { + SigningProfileItem item = (SigningProfileItem) element; + + switch( columnIndex ) { + case 0 : + return item.getKeyLocation(); + case 1 : + return hideString( item.getPassword() ); + case 2 : + return item.getCAPath(); + case 3 : + return item.getRootCAPath(); + } + } + + return Messages.ELEMENT_NOT_FOUND; + } + + protected String hideString(char[] identifier) { + if ( identifier == null ) { + return ""; + } + + StringBuffer result = new StringBuffer(); + for ( int i = 0, length = identifier.length ; i < length; i++ ) { + result.append("*"); + } + + return result.toString(); + } } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningPreferencePage.java b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningPreferencePage.java index f0bcb0790..23d97cc0e 100755 --- a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningPreferencePage.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningPreferencePage.java @@ -34,10 +34,17 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import keycertificategenerator.TizenKeyCertificateGenerator; + +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.*; @@ -60,269 +67,606 @@ import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.ScrollBar; +import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.PlatformUI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.tizen.common.TizenHelpContextIds; import org.tizen.common.sign.Activator; import org.tizen.common.sign.model.Certification.KeyExtension; +import org.tizen.common.sign.model.SignatureConstants; +import org.tizen.common.sign.ui.CertGenerationDialog; +import org.tizen.common.sign.ui.ProfileItemDialog; +import org.tizen.common.sign.ui.CertGenerationDialog.CertDataKey; import org.tizen.common.sign.util.SigningProfileUtil; import org.tizen.common.util.FileUtil; + public class SigningPreferencePage extends PreferencePage implements IWorkbenchPreferencePage { - public static final String PREFERENCE_PAGE_ID = "org.tizen.common.sign.preferences.SigningPreferencePage"; //$NON-NLS-1$ + protected final Logger logger = LoggerFactory.getLogger( this.getClass() ); + + public static final String PREFERENCE_PAGE_ID = "org.tizen.common.sign.preferences.SigningPreferencePage"; private static final int GROUP_VINDENT = 5; - - List<SigningProfile> profileList; - private TableViewer authorTableViewer; - private TableViewer distributorTableViewer; - private TableViewer listViewer; - public static String defaultProfileKey = "defaultprofile"; //$NON-NLS-1$ - public String defaultProfileString; - private Button addButton, removeButton; - private Button clearButton; - private Button distClearButton; - - private IPreferenceStore preferenceStore; + protected TableViewer listViewer; + protected TableViewer authorTableViewer; + protected TableViewer distributorTableViewer; + + protected List<Button> profileDependsButtons; + + + protected SigningProfileContainer container; + + + /** + * Constructor + */ public SigningPreferencePage() { - preferenceStore = Activator.getDefault().getPreferenceStore(); - profileList = new ArrayList<SigningProfile>(); + profileDependsButtons = new ArrayList<Button>(); } - + + /** + * Control creator in the page(or body) + * <ul> + * <li>Profiles group</li> + * <li>Author table group</li> + * <li>Distributor table group</li> + * </ul> + */ @Override protected Control createContents(Composite parent) { - initializeDialogUnits(parent); - List<SigningProfile> _profileList = SigningProfileUtil.populateProfiles(); - if(_profileList != null) { - profileList = _profileList; + + initializeDialogUnits( parent ); + + // load profile + this.container = SigningProfileUtil.getProfileContainerFromFile(); + + // create root composite + Composite composite = createComposite( + parent, SWT.NONE, createGridLayout( 1 ), new GridData( GridData.FILL_BOTH ) ); + + // create child composites + createProfilesControl( composite ); + createAuthorControl( composite ); + createDistributorControl( composite ); + + SigningProfile activeProfile = this.container.getActiveProfile(); + if ( activeProfile != null ) { + enableButtons( true ); + enableTableViewer( true, activeProfile ); } - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout = new GridLayout(); - layout.numColumns = 1; - layout.marginWidth = 0; - layout.marginHeight = 0; - composite.setLayout(layout); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - createProfileListButtons(composite); - createProfileItemsTable(composite); + + validatePreferencePage(); + return parent; } + /** + * Control creator. + * In this, the createContents method is called. + */ @Override public void createControl(Composite parent) { - super.createControl(parent); + super.createControl( parent ); + + // don't show a default button Button defaultButton = getDefaultsButton(); if (defaultButton != null) { - defaultButton.setVisible(false); + defaultButton.setVisible( false ); } - - PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, TizenHelpContextIds.HELP_COMMON_CERTIFICATE_GENERTOR_CONTEXT); + + // set help + PlatformUI.getWorkbench().getHelpSystem().setHelp( + parent, TizenHelpContextIds.HELP_COMMON_CERTIFICATE_GENERTOR_CONTEXT ); } @Override protected void contributeButtons(Composite parent) { - GridLayout layout = createGridLayout(3); - layout.makeColumnsEqualWidth = false; - parent.setLayout(layout); - GridData parentData = new GridData(GridData.FILL_BOTH); + // TODO: set parent layout? why? + parent.setLayout( createGridLayout(3) ); + GridData parentData = new GridData( GridData.FILL_BOTH ); parentData.grabExcessVerticalSpace = false; - parent.setLayoutData(parentData); + parent.setLayoutData( parentData ); + + // TODO: ???? + Composite labelComposite = createComposite( + parent, SWT.NONE, new GridLayout( 2, false ), new GridData( GridData.FILL_HORIZONTAL ) ); + } + + /** + * Profile list group creator + * <ul> + * <li>List viewer</li> + * <li>Buttons</li> + * </ul> + * @param parent + */ + protected void createProfilesControl(Composite parent) { + // profiles group + final Group group = new Group( parent, SWT.NONE ); + group.setText( UIMessages.getString( "org.tizen.common.sign.profilegrouptitle" ) ); + group.setLayout( new GridLayout( 2, false ) ); + group.setLayoutData( new GridData( GridData.FILL_BOTH ) ); - Composite labelComposite = new Composite(parent, SWT.NONE); - GridLayout compLayout = new GridLayout(); - compLayout.numColumns = 2; + Composite profileListComposite = createProfileListViewerControl( group ); + Composite profileButtonComposite = createProfilesButtonControl( group ); - labelComposite.setLayout(compLayout); - GridData compData = new GridData(GridData.FILL_HORIZONTAL); - labelComposite.setLayoutData(compData); + // add control listener + group.addControlListener( new ControlListenerImpl( + group, profileListComposite, profileButtonComposite ) ); } - private void createProfileItemButtons(Composite composite) { + /** + * List viewer creator + * + * @param parent + * @return + */ + protected Composite createProfileListViewerControl(Composite parent) { + final Composite profileListComposite = createComposite( + parent, SWT.NONE, createGridLayout( 1, 0, 3 ), new GridData( GridData.FILL_BOTH ) ); + + // create ListViewer + this.listViewer = new TableViewer( profileListComposite ); + this.listViewer.getTable().setLayoutData( new GridData( GridData.FILL_BOTH ) ); + this.listViewer.setContentProvider( new ListViewerContentProvider( container ) ); - //Add clear button - distClearButton = new Button(composite, SWT.NONE); - distClearButton.setText(UIMessages.getString("org.tizen.common.sign.profileitem.clear")); //$NON-NLS-1$ - distClearButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - distClearButton.setEnabled(false); - distClearButton.addSelectionListener(new SelectionListener() { + // Internal LabelProvider for showing active status + class ListLabelProvider extends LabelProvider implements IFontProvider { @Override - public void widgetSelected(SelectionEvent e) { - Object distItem = distributorTableViewer.getElementAt(0); - if (distItem != null && distItem instanceof SigningProfileItem) { - SigningProfileItem item = (SigningProfileItem)distItem; - item.setIdentifier(EMPTY_STRING); //$NON-NLS-1$ - item.setKeyLocation(EMPTY_STRING); //$NON-NLS-1$ - item.setCAPath(EMPTY_STRING); - item.setRootCAPath(EMPTY_STRING); - item.setPassword(EMPTY_STRING.toCharArray()); - distributorTableViewer.refresh(true); - validatePreferencePage(); - } + public Font getFont(Object element) { + if ( element instanceof SigningProfile ) { + SigningProfile profile = (SigningProfile) element; + + // If an active profile, apply a bold font + String activeProfileName = container.getActiveProfileName(); + + if ( profile.getProfileName().equals( activeProfileName ) ) { + return new Font( Display.getDefault(), boldFont( listViewer.getTable().getFont() ) ); + } + } + + return null; + }; + + @Override + public String getText(Object element) { + if ( element instanceof SigningProfile ) { + String profileName = ( (SigningProfile) element ).getProfileName(); + + // If an active profile, add active string + if ( profileName.equals( container.getActiveProfileName() ) ) { + return profileName + " (Active)"; + } + + // else use default string + return profileName; + } + + return null; } + + @Override + public Image getImage(Object element) { + return super.getImage(element); + } + } + this.listViewer.setLabelProvider( new ListLabelProvider() ); + this.listViewer.addSelectionChangedListener( new ISelectionChangedListener() { @Override - public void widgetDefaultSelected(SelectionEvent e) { + public void selectionChanged(SelectionChangedEvent event) { + SigningProfile selectedProfile = getSelectedProfile( event.getSelection() ); + if ( selectedProfile != null ) { + enableButtons( true ); + enableTableViewer( true, selectedProfile ); + + validatePreferencePage(); + } } }); - //Add profile item button -// addButton = new Button(composite, SWT.NONE); -// addButton.setText( Messages.PROFILES_ADD_BTN ); -// addButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); -// addButton.addSelectionListener(new SelectionListener() { -// @Override -// public void widgetSelected(SelectionEvent e) { -// final IStructuredSelection ss = (IStructuredSelection) listViewer.getSelection(); -// if ( ss.isEmpty() ) -// { -// MessageDialog.openError( getActiveShell(), Messages.ERROR_DIALOG_TITLE, Messages.ERROR_DIALOG_NOT_SELECTED ); -// return ; -// } -// SigningProfileItem profileItem = new SigningProfileItem(); -// profileItem.setAuthor(false); -// profileItem.setIdentifier("%a:%f:%w:%h:%t"); //$NON-NLS-1$ -// profileItem.setKeyLocation(""); //$NON-NLS-1$ -// Object input = distributorTableViewer.getInput(); -// if (input instanceof SigningProfile) { -// SigningProfile profile = (SigningProfile) input; -// profile.addProfileItem(profileItem); -// validatePreferencePage(); -// } -// distributorTableViewer.add(profileItem); -// } -// -// @Override -// public void widgetDefaultSelected(SelectionEvent e) { -// } -// }); -// addButton.setEnabled(false); -// -// //remove profile item button -// removeButton = new Button(composite, SWT.NONE); -// removeButton.setText( Messages.PROFILES_REMOVE_BTN ); -// removeButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); -// removeButton.addSelectionListener(new SelectionListener() { -// @Override -// public void widgetSelected(SelectionEvent e) { -// ISelection selection = distributorTableViewer.getSelection(); -// if (selection instanceof IStructuredSelection) { -// IStructuredSelection strSelection = (IStructuredSelection) selection; -// Object selelement = strSelection.getFirstElement(); -// if (selelement instanceof SigningProfileItem) { -// SigningProfileItem item = (SigningProfileItem) selelement; -// distributorTableViewer.remove(item); -// Object input = distributorTableViewer.getInput(); -// if (input instanceof SigningProfile) { -// SigningProfile profile = (SigningProfile) input; -// profile.removeProfileItem(item); -// validatePreferencePage(); -// } -// } -// } -// } -// -// @Override -// public void widgetDefaultSelected(SelectionEvent e) { -// } -// }); -// removeButton.setEnabled(false); + // set an active profile from the preference information + String activeProfileName = SigningProfileUtil.getActiveProfileName(); + SigningProfile activeProfile = this.container.getProfileByName( activeProfileName ); + this.container.setActiveProfile( activeProfile ); + + // TODO: ???? + this.listViewer.setInput( "profile" ); + + if ( activeProfile != null ) { + this.listViewer.setSelection( new StructuredSelection( activeProfile ) ); + } + + return profileListComposite; } - - private void createProfileItemsTable(Composite composite) { + + protected void enableButtons(boolean isEnable) { + for ( Button button : this.profileDependsButtons ) { + if ( button != null ) { + button.setEnabled( isEnable ); + } + } + } + + protected void enableTableViewer(boolean isEnable, SigningProfile profile) { + if ( authorTableViewer != null ) { + authorTableViewer.getTable().setEnabled( isEnable ); + if ( isEnable && profile != null ) { + SigningProfileItem item = profile.getAuthorProfileItem(); + if ( item == null ) { + item = profile.createEmptyProfileItem( SigningProfile.AUTHOR_ORDINAL ); + } + authorTableViewer.setInput( new SigningProfileItem[] { item } ); + } else { + authorTableViewer.setInput( null ); + } + authorTableViewer.refresh( true ); + } - Group profileItemComosite = new Group(composite, SWT.NONE); - profileItemComosite.setText(UIMessages.getString("org.tizen.common.sign.profileitemgrouptitle")); //$NON-NLS-1$ - GridLayout profileItemLayout = new GridLayout(); - profileItemLayout.numColumns = 1; - profileItemLayout.horizontalSpacing = 4; - profileItemComosite.setLayout(profileItemLayout); - GridData profileData = new GridData(GridData.FILL_BOTH); - profileItemComosite.setLayoutData(profileData); - createAuthorSignatureComp(profileItemComosite); - createDistributorSignatureComp(profileItemComosite); + if ( distributorTableViewer != null ) { + distributorTableViewer.getTable().setEnabled( isEnable ); + if ( isEnable && profile != null ) { + List<SigningProfileItem> items = profile.getDistributorProfileItems(); + for ( int i = 0, length = items.size(); i < length ; i++ ) { + if ( items.get( i ) == null ) { + items.set( i , profile.createEmptyProfileItem( i + 1 ) ); + } + } + + distributorTableViewer.setInput( items.toArray( new SigningProfileItem[0] ) ); + } else { + distributorTableViewer.setInput( null ); + } + distributorTableViewer.refresh( true ); + } } - private GridLayout createGridLayout(int numColumns) { - GridLayout layout = new GridLayout(); - layout.numColumns = numColumns; - layout.marginHeight = 0; - layout.marginWidth = 0; - return layout; + /** + * Profiles group buttons creator + * + * @param parent + * @return + */ + protected Composite createProfilesButtonControl(Composite parent) { + GridData data = new GridData(); + data.verticalAlignment = SWT.TOP; + final Composite profileButtonComposite = createComposite( parent, SWT.NONE, createGridLayout( 1, 0, 3 ), data ); + + // 'add' button + final Button addProfileButton = new Button( profileButtonComposite, SWT.NONE ); + addProfileButton.setText( Messages.PROFILES_ADD_BTN ); + addProfileButton.setLayoutData( new GridData( GridData.FILL_BOTH ) ); + addProfileButton.setToolTipText( Messages.PROFILES_ADD_TOOLTIP ); + addProfileButton.addSelectionListener( new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + // input a profile name from the dialog + InputValidator validator = new InputValidator( container ); + InputDialog dialog = new InputDialog( + Display.getDefault().getActiveShell(), + UIMessages.getString( "org.tizen.common.sign.profilename" ), + UIMessages.getString( "org.tizen.common.sign.entername" ), + EMPTY_STRING, + validator ); + dialog.open(); + + if ( dialog.getReturnCode() == Dialog.OK ) { + String profileName = dialog.getValue().trim(); + + // add new profile + SigningProfile profile = new SigningProfile( profileName ); + profile.createEmptyProfileItem( SigningProfile.AUTHOR_ORDINAL ); + profile.createProfileItemForDeveloper(); + profile.createEmptyProfileItem( 2 ); + + // set active profile + if ( container.getActiveProfile() == null && container.getProfiles().isEmpty() ) { + container.setActiveProfile( profile ); + } else { + container.addProfile( profile ); + } + + // update ListViewer for an active status + listViewer.add( profile ); + listViewer.setSelection( new StructuredSelection( profile ) ); + + // validate page + validatePreferencePage(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + }); + + // 'rename' button + Button modifyProfilesButton = new Button( profileButtonComposite, SWT.NONE ); + modifyProfilesButton.setText( UIMessages.getString( "org.tizen.common.sign.profile.modify" ) ); + modifyProfilesButton.setLayoutData( new GridData( GridData.FILL_BOTH ) ); + modifyProfilesButton.setToolTipText( UIMessages.getString( "org.tizen.common.sign.modifytooltip" ) ); + modifyProfilesButton.addSelectionListener( new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + SigningProfile selectedProfile = getSelectedProfile( listViewer.getSelection() ); + if ( selectedProfile != null ) { + String profileName = selectedProfile.getProfileName(); + + // input a profile name from the dialog with an old profile name + InputValidator validator = new InputValidator( container, profileName ); + InputDialog dialog = new InputDialog( + Display.getDefault().getActiveShell(), + UIMessages.getString("org.tizen.common.sign.profilename"), + UIMessages.getString("org.tizen.common.sign.entername"), + profileName, validator ); + dialog.open(); + + if ( dialog.getReturnCode() == Dialog.OK ) { + container.renameProfile( profileName, dialog.getValue().trim() ); + listViewer.update( selectedProfile, null ); + } + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + }); + + // 'set active' button + Button defaultProfileButton = new Button( profileButtonComposite, SWT.NONE ); + defaultProfileButton.setText( Messages.PROFILES_SETACTIVE_BTN ); + defaultProfileButton.setLayoutData( new GridData( GridData.FILL_BOTH ) ); + defaultProfileButton.setToolTipText( Messages.PROFILES_SETACTIVE_TOOLTIP ); + defaultProfileButton.addSelectionListener( new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + SigningProfile selectedProfile = getSelectedProfile( listViewer.getSelection() ); + if ( selectedProfile != null ) { + // change active profile + container.setActiveProfile( selectedProfile ); + + listViewer.refresh( true ); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + }); + + // 'remove' button + final Button removeProfileButton = new Button( profileButtonComposite, SWT.NONE ); + removeProfileButton.setText( Messages.PROFILES_REMOVE_BTN ); + removeProfileButton.setLayoutData( new GridData( GridData.FILL_BOTH ) ); + removeProfileButton.setToolTipText( Messages.PROFILES_REMOVE_TOOLTIP ); + removeProfileButton.addSelectionListener( new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + SigningProfile selectedProfile = getSelectedProfile( listViewer.getSelection() ); + if ( selectedProfile != null ) { + // remove profile from model + container.removeProfile( selectedProfile ); + + enableButtons( false ); + enableTableViewer( false, selectedProfile ); + + // first profile is set to active profile. + SigningProfile firstProfile = container.getFirstProfile(); + if ( firstProfile != null ) { + container.setActiveProfile( firstProfile ); + listViewer.setSelection( new StructuredSelection( firstProfile ) ); + } + + // remove profile from list viewer + listViewer.remove( selectedProfile ); + listViewer.refresh( true ); + + validatePreferencePage(); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + }); + + return profileButtonComposite; } - - private void createDistributorSignatureComp(Group profileItemComosite) { - Composite distributorComposite = new Composite(profileItemComosite, SWT.NONE); - distributorComposite.setLayout(createGridLayout(1)); - distributorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + protected void createAuthorControl(Composite parent) { + final Group group = new Group( parent, SWT.NONE ); + group.setText( UIMessages.getString("org.tizen.common.sign.authorsigtitle") ); + group.setLayout( new GridLayout( 2, false ) ); + group.setLayoutData( new GridData( GridData.FILL_BOTH ) ); - Label distributorLabel = new Label(distributorComposite, SWT.NONE); - distributorLabel.setText(UIMessages.getString("org.tizen.common.sign.distrisigtitle")); //$NON-NLS-1$ + Composite authorComposite = createAuthorTableViewerControl( group ); + Composite authorButtonComposite = createAuthorButtonControl( group ); - final Composite composite = new Composite(distributorComposite, SWT.NONE); - composite.setLayout(createGridLayout(2)); - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); + group.addControlListener( new ControlListenerImpl( + group, authorComposite, authorButtonComposite ) ); + } - final Composite profileItemTableComposite = new Composite(composite, SWT.NONE); - profileItemTableComposite.setLayout(createGridLayout(1)); - profileItemTableComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - final Table table = new Table(profileItemTableComposite, SWT.BORDER | SWT.FULL_SELECTION); - GridLayout layout = new GridLayout(); - table.setLayout(layout); - table.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + protected void createDistributorControl(Composite parent) { + final Group group = new Group( parent, SWT.NONE ); + group.setText( UIMessages.getString("org.tizen.common.sign.distrisigtitle") ); + group.setLayout( new GridLayout( 2, false ) ); + group.setLayoutData( new GridData( GridData.FILL_BOTH ) ); + + Composite distributorComposite = createDistributorTableViewerControl( group ); + Composite distributorButtonComposite = createDistributorButtonControl( group ); + + group.addControlListener( new ControlListenerImpl( + group, distributorComposite, distributorButtonComposite ) ); + } + + protected Composite createAuthorTableViewerControl(Composite parent) { + final Composite authorComposite = createComposite( + parent, SWT.NONE, createGridLayout( 1, 0, 3 ), new GridData( GridData.FILL_BOTH ) ); + + final Table table = new Table( authorComposite, SWT.BORDER | SWT.FULL_SELECTION ); + table.setLayout( new GridLayout() ); + + GridData tableData = new GridData( GridData.FILL_HORIZONTAL ); + tableData.grabExcessVerticalSpace = false; + table.setLayoutData(tableData); table.setHeaderVisible(true); table.setLinesVisible(true); - - final TableColumn column0 = new TableColumn(table, SWT.NONE, 0); - column0.setText( Messages.PROFILES_COLUMN1 ); //$NON-NLS-1$ - column0.pack(); - - final TableColumn column1 = new TableColumn(table, SWT.NONE, 1); - column1.setText( Messages.PROFILES_COLUMN2 ); //$NON-NLS-1$ - column1.pack(); - final TableColumn column2 = new TableColumn(table, SWT.NONE, 2); - column2.setText( Messages.PROFILES_COLUMN3 ); //$NON-NLS-1$ - column2.pack(); + final TableColumn column0 = createTableColumn( table, SWT.NONE, 0, Messages.PROFILES_COLUMN1); + final TableColumn column1 = createTableColumn( table, SWT.NONE, 1, Messages.PROFILES_COLUMN2); + CellEditor[] editors = { new FileBrowserCellEditor( table ), new PasswordTextCellEditor( table ) }; - final TableColumn column3 = new TableColumn(table, SWT.NONE, 3); - column3.setText( Messages.PROFILES_COLUMN4 ); //$NON-NLS-1$ - column3.pack(); + authorTableViewer = new TableViewer( table ); + authorTableViewer.setColumnProperties( new String[] { + SignatureConstants.PROFILEITEM_ATTR_KEY, + SignatureConstants.PROFILEITEM_ATTR_PASS } ); + authorTableViewer.setCellEditors( editors ); + authorTableViewer.setCellModifier( new ProfileCellModifier( authorTableViewer, this ) ); + authorTableViewer.setContentProvider( new ProfileItemContentProvider() ); + authorTableViewer.setLabelProvider( new ProfileItemLabelProvider() ); + authorTableViewer.getTable().setEnabled( false ); + authorTableViewer.add( new SigningProfileItem() ); + authorTableViewer.add( new SigningProfileItem() ); + authorTableViewer.add( new SigningProfileItem() ); - final CellEditor[] editors = new CellEditor[4]; - editors[0] = new FileBrowserCellEditor(table); - editors[1] = new PasswordTextCellEditor(table); - editors[2] = new FileBrowserCellEditor(table) { + authorComposite.addControlListener( new ControlAdapter() { + public void controlResized(ControlEvent e) { + Rectangle area = authorComposite.getClientArea(); + + Point size = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); + int width = area.width - 15; + if (size.y > area.height + table.getHeaderHeight()) { + width -= 15; + } + Point oldSize = table.getSize(); + if (oldSize.x > area.width) { + column0.setWidth((int) (width * .75)); + column1.setWidth(width - column0.getWidth()); + table.setSize(area.width, area.height); + } else { + table.setSize(area.width, area.height); + column0.setWidth((int) (width * .75)); + column1.setWidth(width - column0.getWidth()); + } + } + }); + + return authorComposite; + } + + protected Composite createAuthorButtonControl(Composite parent) { + GridData data = new GridData(); + data.verticalAlignment = SWT.TOP; + final Composite authorButtonComposite = createComposite( parent, SWT.NONE, createGridLayout( 1, 0, 3 ), data ); + + Button genButton = new Button( authorButtonComposite, SWT.NONE ); + genButton.setText( "Generate" ); + genButton.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); + genButton.setEnabled( false ); + genButton.addSelectionListener( new SelectionListener() { @Override - protected String[] getDialogFilter() { - return new String[]{"*.cer"}; + public void widgetSelected(SelectionEvent e) { + generateCertificate(); } - }; - editors[3] = new FileBrowserCellEditor(table) { + @Override - protected String[] getDialogFilter() { - return new String[]{"*.cer"}; + public void widgetDefaultSelected(SelectionEvent e) {} + } ); + + this.profileDependsButtons.add( genButton ); + + Button editButton = new Button( authorButtonComposite, SWT.NONE ); + editButton.setText( "Edit" ); + editButton.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); + editButton.setEnabled( false ); + editButton.addSelectionListener( new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + SigningProfile profile = getSelectedProfile( listViewer.getSelection() ); + SigningProfileItem item = profile.getAuthorProfileItem(); + + ProfileItemDialog dialog = new ProfileItemDialog( Display.getDefault().getActiveShell(), item ); + int result = dialog.open(); + if ( result == ProfileItemDialog.OK ) { + item.setKeyLocation( dialog.getKeyPath() ); + item.setPassword( dialog.getPassword() ); + item.setCAPath( dialog.getCaPath() ); + item.setRootCAPath( dialog.getRootPath() ); + + enableTableViewer( true, profile ); + + validatePreferencePage(); + } } + + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + } ); + + this.profileDependsButtons.add( editButton ); + + return authorButtonComposite; + } + + protected Composite createDistributorTableViewerControl(Composite parent) { + final Composite distributorComposite = createComposite( + parent, SWT.NONE, createGridLayout( 1, 0, 3 ), new GridData( GridData.FILL_BOTH ) ); + + final Table table = new Table( distributorComposite, SWT.BORDER | SWT.FULL_SELECTION ); + table.setLayout( new GridLayout() ); + table.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); + + table.setHeaderVisible(true); + table.setLinesVisible(true); + + final TableColumn column0 = createTableColumn( table, SWT.NONE, 0, Messages.PROFILES_COLUMN1 ); + final TableColumn column1 = createTableColumn( table, SWT.NONE, 1, Messages.PROFILES_COLUMN2 ); + final TableColumn column2 = createTableColumn( table, SWT.NONE, 2, Messages.PROFILES_COLUMN3 ); + final TableColumn column3 = createTableColumn( table, SWT.NONE, 3, Messages.PROFILES_COLUMN4 ); + + CellEditor[] editors = { + new FileBrowserCellEditor( table ), + new PasswordTextCellEditor( table ), + new FileBrowserCellEditor( table ) { + @Override + protected String[] getDialogFilter() { + return new String[]{"*.cer"}; + } + }, + new FileBrowserCellEditor( table ) { + @Override + protected String[] getDialogFilter() { + return new String[]{"*.cer"}; + } + } }; - - distributorTableViewer = new TableViewer(table); - distributorTableViewer.setColumnProperties(new String[] { SigningProfileUtil.ITEM_ATTR_KEY, SigningProfileUtil.ITEM_ATTR_PASS, SigningProfileUtil.ITEM_ATTR_CA, SigningProfileUtil.ITEM_ATTR_ROOTCA }); - distributorTableViewer.setCellEditors(editors); - distributorTableViewer.setCellModifier(new ProfileCellModifier(distributorTableViewer, this)); - distributorTableViewer.setContentProvider(new ProfileItemContentProvider()); - distributorTableViewer.setLabelProvider(new ProfileItemLabelProvider()); - table.setEnabled(false); - profileItemTableComposite.addControlListener(new ControlAdapter() { + distributorTableViewer = new TableViewer( table ); + distributorTableViewer.setColumnProperties( new String[] { + SignatureConstants.PROFILEITEM_ATTR_KEY, + SignatureConstants.PROFILEITEM_ATTR_PASS, + SignatureConstants.PROFILEITEM_ATTR_CA, + SignatureConstants.PROFILEITEM_ATTR_ROOTCA } ); + distributorTableViewer.setCellEditors( editors ); + distributorTableViewer.setCellModifier( new ProfileCellModifier( distributorTableViewer, this ) ); + distributorTableViewer.setContentProvider( new ProfileItemContentProvider() ); + distributorTableViewer.setLabelProvider( new ProfileItemLabelProvider() ); + distributorTableViewer.getTable().setEnabled( false ); + distributorTableViewer.add( new SigningProfileItem() ); + distributorTableViewer.add( new SigningProfileItem() ); + distributorTableViewer.add( new SigningProfileItem() ); + distributorTableViewer.add( new SigningProfileItem() ); + + distributorComposite.addControlListener( new ControlAdapter() { public void controlResized(ControlEvent e) { - Rectangle area = profileItemTableComposite.getClientArea(); + Rectangle area = distributorComposite.getClientArea(); Point size = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); ScrollBar vBar = table.getVerticalBar(); @@ -350,45 +694,57 @@ public class SigningPreferencePage extends PreferencePage implements IWorkbenchP } }); - final Composite profileItemButtonComposite = new Composite(composite, SWT.NONE); - GridLayout profileItemButtonLayout = new GridLayout(); - profileItemButtonLayout.numColumns = 1; - profileItemButtonLayout.marginWidth = 0; - profileItemButtonComposite.setLayout(profileItemButtonLayout); + return distributorComposite; + } + + protected Composite createDistributorButtonControl(Composite parent) { GridData data = new GridData(); data.verticalAlignment = SWT.TOP; - profileItemButtonComposite.setLayoutData(data); - createProfileItemButtons(profileItemButtonComposite); - String defaultProfile = preferenceStore.getString(defaultProfileKey); - if (defaultProfile != null) { - for (SigningProfile profile : profileList) { - if (defaultProfile.equals(profile.getProfileName())) { - if (addButton != null) { - addButton.setEnabled(true); - } - if (removeButton != null) { - removeButton.setEnabled(true); - } - if (clearButton != null) { - clearButton.setEnabled(true); - } - if (distClearButton != null) { - distClearButton.setEnabled(true); - } - distributorTableViewer.getTable().setEnabled(true); - distributorTableViewer.setInput(profile); - authorTableViewer.getTable().setEnabled(true); - authorTableViewer.setInput(profile); + final Composite distributorButtonComposite = createComposite( parent, SWT.NONE, createGridLayout( 1, 0, 3 ), data ); + + Button dist1EditButton = new Button( distributorButtonComposite, SWT.NONE ); + dist1EditButton.setText( "Edit" ); + dist1EditButton.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); + dist1EditButton.setEnabled( false ); + dist1EditButton.addSelectionListener( new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent e) { + Shell activeShell = Display.getDefault().getActiveShell(); + SigningProfileItem selectedItem = getSelectedProfileItem( distributorTableViewer.getSelection() ); + if ( selectedItem == null ) { + MessageDialog.openError( + activeShell, + "Certificate editor error", + "Not selected a distributor item for modification" ); + return; + } + + SigningProfile profile = getSelectedProfile( listViewer.getSelection() ); + SigningProfileItem item = profile.getProfileItem( profile.getOrdinal( selectedItem ) ); + + ProfileItemDialog itemDialog = new ProfileItemDialog( activeShell, item ); + int result = itemDialog.open(); + if ( result == ProfileItemDialog.OK ) { + item.setKeyLocation( itemDialog.getKeyPath() ); + item.setPassword( itemDialog.getPassword() ); + item.setCAPath( itemDialog.getCaPath() ); + item.setRootCAPath( itemDialog.getRootPath() ); + + enableTableViewer( true, profile ); + + validatePreferencePage(); } } - } + + @Override + public void widgetDefaultSelected(SelectionEvent e) {} + } ); - if(distributorTableViewer.getTable().getItemCount() == 0) { - distributorTableViewer.add(new SigningProfileItem()); - } - composite.addControlListener(new ControlListenerImpl(composite, profileItemTableComposite, profileItemButtonComposite)); + this.profileDependsButtons.add( dist1EditButton ); + + return distributorButtonComposite; } - + protected Composite createNoteComposite(Font font, Composite composite, String title, String message, SelectionListener listener) { Composite messageComposite = new Composite(composite, SWT.NONE); @@ -416,419 +772,41 @@ public class SigningPreferencePage extends PreferencePage implements IWorkbenchP } private void addNote(Composite parent, String noteMessage, SelectionListener listener) { - Composite noteControl= createNoteComposite(JFaceResources.getDialogFont(), parent, - "Note:", noteMessage, listener); - GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL); - gd.verticalIndent = GROUP_VINDENT; - noteControl.setLayoutData(gd); - } - - private void createAuthorSignatureComp(final Group profileItemComosite) { - - //Create author signature group - Composite authorComposite = new Composite(profileItemComosite, SWT.NONE); - authorComposite.setLayout(createGridLayout(1)); - authorComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - Label authorLabel = new Label(authorComposite, SWT.NONE); - authorLabel.setText(UIMessages.getString("org.tizen.common.sign.authorsigtitle")); //$NON-NLS-1$ - - addNote(authorComposite, UIMessages.getString("org.tizen.common.sign.note.certificate_generator"), new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - PlatformUI.getWorkbench().getHelpSystem().displayHelp(TizenHelpContextIds.HELP_COMMON_CERTIFICATE_GENERTOR_CONTEXT); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - final Composite composite = new Composite(authorComposite, SWT.NONE); - composite.setLayout(createGridLayout(2)); - GridData data = new GridData(GridData.FILL_BOTH); - composite.setLayoutData(data); - - final Composite authorItemTableComposite = new Composite(composite, SWT.NONE); - authorItemTableComposite.setLayout(createGridLayout(1)); - GridData authorTableData = new GridData(GridData.FILL_BOTH); - authorItemTableComposite.setLayoutData(authorTableData); - - final Table table = new Table(authorItemTableComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.NO_SCROLL); - GridLayout layout = new GridLayout(); - table.setLayout(layout); - GridData tableData = new GridData(GridData.FILL_HORIZONTAL); - tableData.grabExcessVerticalSpace = false; - table.setLayoutData(tableData); - table.setHeaderVisible(true); - table.setLinesVisible(true); - - final TableColumn column0 = new TableColumn(table, SWT.NONE, 0); - column0.setText( Messages.PROFILES_COLUMN1 ); //$NON-NLS-1$ - column0.pack(); - - final TableColumn column1 = new TableColumn(table, SWT.NONE, 1); - column1.setText( Messages.PROFILES_COLUMN2 ); //$NON-NLS-1$ - column1.pack(); - - final CellEditor[] editors = new CellEditor[2]; - editors[0] = new FileBrowserCellEditor(table); - editors[1] = new PasswordTextCellEditor(table); - - authorTableViewer = new TableViewer(table); - authorTableViewer.setColumnProperties(new String[] { SigningProfileUtil.ITEM_ATTR_KEY, SigningProfileUtil.ITEM_ATTR_PASS}); - authorTableViewer.setCellEditors(editors); - authorTableViewer.setCellModifier(new ProfileCellModifier(authorTableViewer, this)); - authorTableViewer.getTable().setEnabled(false); - authorTableViewer.setContentProvider(new IStructuredContentProvider() { - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - - @Override - public void dispose() { - } - - @Override - public Object[] getElements(Object inputElement) { - if (inputElement instanceof SigningProfile) { - SigningProfile profile = (SigningProfile)inputElement; - if (profile.getAuthorItem() != null) { - return new SigningProfileItem[] {((SigningProfile)inputElement).getAuthorItem()}; - } - } - return null; - } - }); - authorTableViewer.setLabelProvider(new ProfileItemLabelProvider()); - authorTableViewer.add(new SigningProfileItem()); - - authorItemTableComposite.addControlListener(new ControlAdapter() { - public void controlResized(ControlEvent e) { - Rectangle area = authorItemTableComposite.getClientArea(); - - Point size = table.computeSize(SWT.DEFAULT, SWT.DEFAULT); - int width = area.width - 15; - if (size.y > area.height + table.getHeaderHeight()) { - width -= 15; - } - Point oldSize = table.getSize(); - if (oldSize.x > area.width) { - column0.setWidth((int) (width * .75)); - column1.setWidth(width - column0.getWidth()); - table.setSize(area.width, area.height); - } else { - table.setSize(area.width, area.height); - column0.setWidth((int) (width * .75)); - column1.setWidth(width - column0.getWidth()); - } - } - }); - - final Composite authorItemButtonComposite = new Composite(composite, SWT.NONE); - GridData clearButtonData = new GridData(); - clearButtonData.verticalAlignment = SWT.TOP; - authorItemButtonComposite.setLayout(createGridLayout(1)); - authorItemButtonComposite.setLayoutData(clearButtonData); - - clearButton = new Button(authorItemButtonComposite, SWT.NONE); - clearButton.setText(UIMessages.getString("org.tizen.common.sign.profileitem.clear")); //$NON-NLS-1$ - clearButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - clearButton.setEnabled(false); - clearButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - Object authorItem = authorTableViewer.getElementAt(0); - if (authorItem != null && authorItem instanceof SigningProfileItem) { - SigningProfileItem item = (SigningProfileItem)authorItem; - item.setPassword(EMPTY_STRING.toCharArray()); //$NON-NLS-1$ - item.setKeyLocation(""); //$NON-NLS-1$ - authorTableViewer.refresh(true); - validatePreferencePage(); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - composite.addControlListener(new ControlListenerImpl(composite, authorItemTableComposite, authorItemButtonComposite)); - } - - private void createProfileListButtons(Composite composite) { - - final Group profileComposite = new Group(composite, SWT.NONE); - profileComposite.setText(UIMessages.getString("org.tizen.common.sign.profilegrouptitle")); //$NON-NLS-1$ - GridLayout profileLayout = new GridLayout(); - profileLayout.numColumns = 2; - profileLayout.makeColumnsEqualWidth = false; - profileComposite.setLayout(profileLayout); - GridData profileData = new GridData(GridData.FILL_BOTH); - profileComposite.setLayoutData(profileData); - - final Composite profileListComposite = new Composite(profileComposite, SWT.NONE); - GridLayout profileListLayout = new GridLayout(); - profileListLayout.numColumns = 1; - profileListLayout.marginWidth = 0; - profileListLayout.marginHeight = 3; - profileListComposite.setLayout(profileListLayout); - GridData listCompositeData = new GridData(GridData.FILL_BOTH); - profileListComposite.setLayoutData(listCompositeData); - - final Composite profileButtonComposite = new Composite(profileComposite, SWT.NONE); - GridLayout profileButtonLayout = new GridLayout(); - profileButtonLayout.numColumns = 1; - profileButtonLayout.marginWidth = 0; - profileButtonLayout.marginHeight = 3; - GridData data = new GridData(); - data.verticalAlignment = SWT.TOP; - profileButtonComposite.setLayout(profileButtonLayout); - profileButtonComposite.setLayoutData(data); - - profileComposite.addControlListener(new ControlListenerImpl(profileComposite, profileListComposite, profileButtonComposite)); - - final Button addProfileButton = new Button(profileButtonComposite, SWT.NONE); - addProfileButton.setText( Messages.PROFILES_ADD_BTN ); - addProfileButton.setLayoutData(new GridData(GridData.FILL_BOTH)); - addProfileButton.setToolTipText( Messages.PROFILES_ADD_TOOLTIP ); - addProfileButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - InputValidator validator = new InputValidator(profileList); - InputDialog dialog = new InputDialog(Display.getDefault().getActiveShell(), UIMessages.getString("org.tizen.common.sign.profilename"), UIMessages.getString("org.tizen.common.sign.entername"), "", validator); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - dialog.open(); - if (dialog.getReturnCode() == Dialog.OK) { - SigningProfile profile = new SigningProfile(); - profile.setProfileName(dialog.getValue().trim()); - SigningProfileItem authorProfileItem = new SigningProfileItem(); - authorProfileItem.setAuthor(true); - authorProfileItem.setIdentifier(EMPTY_STRING); //$NON-NLS-1$ - authorProfileItem.setKeyLocation(EMPTY_STRING); //$NON-NLS-1$ - authorProfileItem.setCAPath( SigningProfileUtil.getAuthorCAPath() ); - authorProfileItem.setRootCAPath(EMPTY_STRING); - profile.setAuthorItem(authorProfileItem); - profileList.add(profile); - if ("".equals(defaultProfileString) && profileList.size() == 1) { //$NON-NLS-1$ - defaultProfileString = dialog.getValue().trim(); - } - listViewer.add(profile); - listViewer.setSelection(new StructuredSelection(profile)); - validatePreferencePage(); - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - Button modifyProfilesButton = new Button(profileButtonComposite, SWT.NONE); - modifyProfilesButton.setText(UIMessages.getString("org.tizen.common.sign.profile.modify")); //$NON-NLS-1$ - modifyProfilesButton.setLayoutData(new GridData(GridData.FILL_BOTH)); - modifyProfilesButton.setToolTipText(UIMessages.getString("org.tizen.common.sign.modifytooltip")); //$NON-NLS-1$ - modifyProfilesButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - ISelection selection = listViewer.getSelection(); - if (selection instanceof IStructuredSelection) { - Object object = ((IStructuredSelection) selection).getFirstElement(); - if (object instanceof SigningProfile) { - SigningProfile profile = (SigningProfile) object; - InputValidator validator = new InputValidator(profileList, profile.getProfileName()); - InputDialog dialog = new InputDialog(Display.getDefault().getActiveShell(), UIMessages.getString("org.tizen.common.sign.profilename"), UIMessages.getString("org.tizen.common.sign.entername"), profile.getProfileName(), validator); //$NON-NLS-1$ //$NON-NLS-2$ - dialog.open(); - if (dialog.getReturnCode() == Dialog.OK) { - if (((SigningProfile) object).getProfileName().compareTo(defaultProfileString) == 0) { - defaultProfileString = dialog.getValue().trim(); - } - ((SigningProfile) object).setProfileName(dialog.getValue().trim()); - listViewer.update(object, null); - } - } - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - Button defaultProfileButton = new Button(profileButtonComposite, SWT.NONE); - defaultProfileButton.setText( Messages.PROFILES_SETACTIVE_BTN ); - defaultProfileButton.setLayoutData(new GridData(GridData.FILL_BOTH)); - defaultProfileButton.setToolTipText( Messages.PROFILES_SETACTIVE_TOOLTIP ); - defaultProfileButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - ISelection selection = listViewer.getSelection(); - if (selection instanceof IStructuredSelection) { - Object object = ((IStructuredSelection) selection).getFirstElement(); - if (object instanceof SigningProfile) { - defaultProfileString = ((SigningProfile) object).getProfileName(); - listViewer.refresh(true); - } - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - final Button removeProfileButton = new Button(profileButtonComposite, SWT.NONE); - removeProfileButton.setText( Messages.PROFILES_REMOVE_BTN ); - removeProfileButton.setLayoutData(new GridData(GridData.FILL_BOTH)); - removeProfileButton.setToolTipText( Messages.PROFILES_REMOVE_TOOLTIP ); - removeProfileButton.addSelectionListener(new SelectionListener() { - @Override - public void widgetSelected(SelectionEvent e) { - ISelection selection = listViewer.getSelection(); - if (selection instanceof IStructuredSelection) { - Object object = ((IStructuredSelection) selection).getFirstElement(); - if (object instanceof SigningProfile) { - profileList.remove(object); - if (((SigningProfile) object).getProfileName().compareTo(defaultProfileString) == 0) { - defaultProfileString = EMPTY_STRING; - } - if (addButton != null) { - addButton.setEnabled(false); - } - if (removeButton != null) { - removeButton.setEnabled(false); - } - if (clearButton != null) { - clearButton.setEnabled(false); - authorTableViewer.getTable().setEnabled(false); - } - if (distClearButton != null) { - distClearButton.setEnabled(true); - } - if (profileList.size() == 1) { - SigningProfile profile = profileList.get(0); - if (profile != null) { - defaultProfileString = profile.getProfileName(); - listViewer.setSelection(new StructuredSelection(profile)); - } - } - listViewer.remove(object); - listViewer.refresh(true); - distributorTableViewer.remove(((SigningProfile) object).getProfileItemList().toArray()); - authorTableViewer.remove(((SigningProfile) object).getAuthorItem()); - validatePreferencePage(); - } - } - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); +// usage : +// addNote(authorComposite, UIMessages.getString("org.tizen.common.sign.note.certificate_generator"), new SelectionListener() { +// @Override +// public void widgetSelected(SelectionEvent e) { +// PlatformUI.getWorkbench().getHelpSystem().displayHelp(TizenHelpContextIds.HELP_COMMON_CERTIFICATE_GENERTOR_CONTEXT); +// } +// +// @Override +// public void widgetDefaultSelected(SelectionEvent e) { +// } +// }); - listViewer = new TableViewer(profileListComposite); - GridData listData = new GridData(GridData.FILL_BOTH); - listViewer.getTable().setLayoutData(listData); - listViewer.setContentProvider(new ListViewerContentProvider(profileList)); - - class ListLabelProvider extends LabelProvider implements IFontProvider{ - @Override - public Font getFont(Object element) { - if (element instanceof SigningProfile) { - if (defaultProfileString != null && ((SigningProfile) element).profileName.compareTo(defaultProfileString) == 0) { - return new Font(Display.getDefault(), boldFont(listViewer.getTable().getFont())); - } - } - return null; - }; - - public String getText(Object element) { - if (element instanceof SigningProfile) { - if (defaultProfileString != null && ((SigningProfile) element).profileName.compareTo(defaultProfileString) == 0) { - return ((SigningProfile) element).profileName + " (Active)"; //$NON-NLS-1$ - } - return ((SigningProfile) element).profileName; - } - return null; - } - - @Override - public Image getImage(Object element) { - return super.getImage(element); - } - } - listViewer.setLabelProvider(new ListLabelProvider()); - - listViewer.addSelectionChangedListener(new ISelectionChangedListener() { - @Override - public void selectionChanged(SelectionChangedEvent event) { - ISelection selection = event.getSelection(); - if (selection instanceof IStructuredSelection) { - StructuredSelection structuredSel = (StructuredSelection) selection; - Object selElement = structuredSel.getFirstElement(); - if (selElement instanceof SigningProfile) { - if (addButton != null) { - addButton.setEnabled(true); - } - if (removeButton != null) { - removeButton.setEnabled(true); - } - if (clearButton != null) { - clearButton.setEnabled(true); - } - if (distClearButton != null) { - distClearButton.setEnabled(true); - } - - SigningProfile profile = (SigningProfile) selElement; - if (distributorTableViewer != null) { - distributorTableViewer.getTable().setEnabled(true); - distributorTableViewer.setInput(profile); - } - if (authorTableViewer != null) { - authorTableViewer.getTable().setEnabled(true); - authorTableViewer.setInput(profile); - } - - if(distributorTableViewer != null && distributorTableViewer.getTable().getItemCount() == 0) { - SigningProfileItem profileItem = new SigningProfileItem(); - profileItem.setAuthor(false); - profileItem.setIdentifier(EMPTY_STRING); //$NON-NLS-1$ - profileItem.setKeyLocation(EMPTY_STRING); //$NON-NLS-1$ - profileItem.setCAPath(EMPTY_STRING); - profileItem.setRootCAPath(EMPTY_STRING); - profile.addProfileItem(profileItem); - validatePreferencePage(); - distributorTableViewer.add(profileItem); - } - } - } - } - }); - defaultProfileString = preferenceStore.getString(defaultProfileKey); - listViewer.setInput("profile"); //$NON-NLS-1$ - if (defaultProfileString != null) { - for (SigningProfile profile : profileList) { - if (defaultProfileString.equals(profile.getProfileName())) { - listViewer.setSelection(new StructuredSelection(profile)); - } - } - } + Composite noteControl= createNoteComposite( + JFaceResources.getDialogFont(), parent, "Note:", noteMessage, listener); + GridData gd = new GridData( GridData.HORIZONTAL_ALIGN_FILL ); + gd.verticalIndent = GROUP_VINDENT; + noteControl.setLayoutData( gd ); } @Override protected void performDefaults() { } - private void checkFile(String filePath) { + private void checkFile(String filePath, String validExtension) { if (filePath != null && filePath.trim().length() > 0) { File file = new File(filePath); + boolean isValid = true; if (!file.exists() || !file.isFile()) { isValid = false; } else { String fileExtension = FileUtil.getFileExtension( filePath ); - isValid = KeyExtension.p12.name().equalsIgnoreCase( fileExtension ); + isValid = validExtension.equalsIgnoreCase( fileExtension ); } + if (!isValid) { setValid(false); setErrorMessage(filePath + ": " + UIMessages.getString("org.tizen.common.sign.entervalidp12")); @@ -839,33 +817,23 @@ public class SigningPreferencePage extends PreferencePage implements IWorkbenchP protected void validatePreferencePage() { setValid(true); setErrorMessage(null); - for (SigningProfile profile : profileList) { - if (profile == null) - { - continue; - } - - List<SigningProfileItem> profileItemList = profile.getProfileItemList(); - for (SigningProfileItem item : profileItemList) { - if (item == null) - { + + for ( SigningProfile profile : container.getProfiles() ) { + for ( SigningProfileItem item : profile.getProfileItems() ) { + if ( item == null ) { continue; } - - checkFile(item.getKeyLocation()); - } - - SigningProfileItem authorItem = profile.getAuthorItem(); - if (authorItem != null) - { - checkFile(authorItem.getKeyLocation()); + + checkFile( item.getKeyLocation(), KeyExtension.p12.name() ); + + checkFile( item.getCAPath(), "cer" ); + checkFile( item.getRootCAPath(), "cer" ); } - } + } } @Override - public void init(IWorkbench workbench) { - } + public void init(IWorkbench workbench) {} public FontData[] boldFont(Font font) { FontData[] datas = font.getFontData(); @@ -885,11 +853,121 @@ public class SigningPreferencePage extends PreferencePage implements IWorkbenchP @Override public boolean performOk() { - preferenceStore.setValue(defaultProfileKey, defaultProfileString); - SigningProfileUtil.writeProfilesAndProfileItems(this.profileList); + SigningProfileUtil.setActiveProfileName( container.getActiveProfileName() ); + SigningProfileUtil.writeProfilesToFile( container ); + return super.performOk(); } + protected void generateCertificate() { + Shell activeShell = Display.getDefault().getActiveShell(); + + CertGenerationDialog dialog = new CertGenerationDialog( activeShell ); + int result = dialog.open(); + if ( result != ProfileItemDialog.OK ) { + return; + } + +// IPath certPath = SigningProfileUtil.getAuthorCertStorePath().append( dialog.getValue( CertDataKey.KeyName ) ); + IPath certPath = new Path( dialog.getValue( CertDataKey.KeyName ) ); + if ( isEmpty( certPath.getFileExtension() ) ) { + certPath = certPath.addFileExtension( "p12" ); + } + logger.debug( "generate a certificate to {}", certPath ); + + try { + TizenKeyCertificateGenerator.KeyCertGeneratorFromIde( + dialog.getValue( CertDataKey.Country ), + dialog.getValue( CertDataKey.State ), + dialog.getValue( CertDataKey.City ), + dialog.getValue( CertDataKey.Name ), + dialog.getValue( CertDataKey.Organization ), + dialog.getValue( CertDataKey.Department ), + dialog.getValue( CertDataKey.Email ), + dialog.getValue( CertDataKey.Password ), + dialog.getValue( CertDataKey.Alias ), + certPath.toPortableString() ); + } catch (Exception e) { + logger.error( e.getMessage(), e ); + ErrorDialog.openError( + activeShell, + "Certificate generator error", + "Failed to generate a certificate.", + new Status( IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e ) ); + return; + } + + String absolutePath = certPath.toFile().getAbsolutePath(); + String successMsg = "A certificate is generated to '" + absolutePath +"'.\n" + + "Do you want to fill the author certificate information automatically?"; + boolean bAutoFill = MessageDialog.openQuestion( activeShell, "Generation success", successMsg ); + + if ( bAutoFill ) { + SigningProfile profile = getSelectedProfile( listViewer.getSelection() ); + SigningProfileItem item = profile.getAuthorProfileItem(); + + item.setKeyLocation( absolutePath ); + item.setPassword( dialog.getValue( CertDataKey.Password ).toCharArray() ); + + enableTableViewer( true, profile ); + + validatePreferencePage(); + } + } + + private GridLayout createGridLayout(int numColumns) { + return createGridLayout(numColumns, 0, 0); + } + + private GridLayout createGridLayout(int numColumns, int marginHeight, int marginWidth) { + GridLayout layout = new GridLayout( numColumns, false ); + layout.marginHeight = marginHeight; + layout.marginWidth = marginWidth; + + return layout; + } + + private Composite createComposite(Composite parent, int style, Layout layout, Object layoutData) { + Composite composite = new Composite( parent, SWT.NONE ); + composite.setLayout( layout ); + composite.setLayoutData( layoutData ); + + return composite; + } + + private TableColumn createTableColumn(Table parent, int style, int index, String text) { + final TableColumn column = new TableColumn( parent, style, index ); + column.setText( text ); + column.pack(); + + return column; + } + + private SigningProfile getSelectedProfile(final ISelection selection) { + if ( selection instanceof IStructuredSelection ) { + Object firstElement = ( (StructuredSelection) selection ).getFirstElement(); + if ( firstElement instanceof SigningProfile ) { + return (SigningProfile) firstElement; + } + } + + return null; + } + + private SigningProfileItem getSelectedProfileItem(final ISelection selection) { + if ( selection instanceof IStructuredSelection ) { + Object firstElement = ( (StructuredSelection) selection ).getFirstElement(); + if ( firstElement instanceof SigningProfileItem ) { + return (SigningProfileItem) firstElement; + } + } + + return null; + } + + /** + * TextCellEditor for password processing + */ public class PasswordTextCellEditor extends TextCellEditor { public PasswordTextCellEditor(Composite composite) { @@ -898,14 +976,7 @@ public class SigningPreferencePage extends PreferencePage implements IWorkbenchP @Override protected void doSetValue(Object value) { - String _value = null; - if(value == null) { - _value = ""; - } - else if(value instanceof char[]) { - _value = new String((char[])value); - } - super.doSetValue(_value); + super.doSetValue( ( value instanceof char[] ) ? new String( (char[]) value ) : EMPTY_STRING ); } @Override @@ -948,74 +1019,70 @@ class ControlListenerImpl implements ControlListener { class ListViewerContentProvider implements IStructuredContentProvider { - private List<SigningProfile> list; + private SigningProfileContainer container; - public ListViewerContentProvider(List<SigningProfile> list) { - this.list = list; + public ListViewerContentProvider(SigningProfileContainer container) { + this.container = container; } @Override public Object[] getElements(Object inputElement) { - if (inputElement instanceof String) { - SigningProfile[] profileItems = new SigningProfile[list.size()]; - if (((String) inputElement).compareTo("profile") == 0) { //$NON-NLS-1$ - for (int i=0;i<list.size();i++) { - profileItems[i] = list.get(i); - } + if ( inputElement instanceof String ) { + if ( "profile".equals( (String) inputElement ) ) { + return container.getProfiles().toArray( new SigningProfile[0] ); } - return profileItems; + + return new SigningProfile[0]; } + return null; } @Override - public void dispose() { - } + public void dispose() {} @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} } class InputValidator implements IInputValidator { - protected final String profileName; - protected final List<SigningProfile> list; + protected final String oldProfileName; - InputValidator(List<SigningProfile> profileList) { - this( profileList, null ); + protected final SigningProfileContainer container; + + + InputValidator(final SigningProfileContainer container) { + this( container, null ); } - InputValidator(List<SigningProfile> profileList, final String profileName ) { - this.list = profileList; - this.profileName = profileName; + InputValidator(final SigningProfileContainer container, final String oldProfileName ) { + this.container = container; + this.oldProfileName = oldProfileName; } + /** + * @return String an error message or null if no error + */ + @Override public String isValid(String newText) { - if ( isEmpty( newText ) ) - { - return EMPTY_STRING; - } - final String safeText = trim( newText ); - - if ( null != profileName && profileName.equals( safeText ) ) - { - return null; - } - if (checkForDuplicateProfile(newText.trim())) { - return UIMessages.getString("org.tizen.common.sign.profile") + " " + safeText + " " + UIMessages.getString("org.tizen.common.sign.aldreadyexists"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ - } else { - return null; - } - } - - protected boolean checkForDuplicateProfile(String string) { - for (SigningProfile profile : list) { - if (profile.getProfileName().compareTo(string) == 0) { - return true; - } + // check the empty profile name + if ( isEmpty( newText ) ) { + return EMPTY_STRING; // return an empty error } - return false; + + // check the same with previous name + final String safeText = trim( newText ); + if ( null != oldProfileName && oldProfileName.equals( safeText ) ) { + return "This is the same with previous name"; + } + + // check the already existent profile name + if ( container.containsProfile( newText.trim() ) ) { + return UIMessages.getString( "org.tizen.common.sign.profile" ) + " " + safeText + " " + UIMessages.getString( "org.tizen.common.sign.aldreadyexists" ); + } + + return null; } } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningProfile.java b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningProfile.java index 9d38153d2..97ba69efa 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningProfile.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningProfile.java @@ -26,65 +26,337 @@ */ package org.tizen.common.sign.preferences; +import java.security.InvalidKeyException; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tizen.common.sign.model.SignatureConstants; +import org.tizen.common.sign.util.SigningPathUtil; +import org.tizen.common.sign.util.XMLUtil; +import org.tizen.common.util.Assert; +import org.tizen.common.util.CipherUtil; +import org.tizen.common.util.ParsingUtil; +import org.tizen.common.util.StringUtil; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + public class SigningProfile { + protected final Logger logger = LoggerFactory.getLogger( this.getClass() ); + protected String profileName; - protected SigningProfileItem authorItem = null; - protected final List<SigningProfileItem> profileItemList = new ArrayList<SigningProfileItem>(); + protected final Map<Integer, SigningProfileItem> profileItemMap; + // <Distributor ordinal number, Profile item>. + + public final static int AUTHOR_ORDINAL = 0; // If the ordinal number is zero, this is an author + public final static int MAX_DISTRIBUTOR = 2; + public final static int NOTHING = -1; + + + /** + * Constructor + * + * @param profileName initial name + */ + public SigningProfile(String profileName) { + Assert.notNull( profileName ); + + this.profileName = profileName; + + this.profileItemMap = new HashMap<Integer, SigningProfileItem>(); + + for ( int i = 0; i <= MAX_DISTRIBUTOR; i++ ) { + this.profileItemMap.put( i, null ); + } + } + /** + * Profile name getter + * @return + */ public String getProfileName() { return profileName; } + /** + * Setter for renaming + * @param profileName + */ public void setProfileName(String profileName) { + Assert.notNull( profileName ); + this.profileName = profileName; } - public void addProfileItem(SigningProfileItem item) { - this.profileItemList.add( item ); + /** + * @param item profile item + * @param ordinal If zero, this is an author. If not zero, this is an ordinal number of distributor. + */ + public void setProfileItem(int ordinal, SigningProfileItem item) { + Assert.isTrue( ordinal >= 0 && ordinal <= MAX_DISTRIBUTOR ); + + this.profileItemMap.put( ordinal, item ); } - public void removeProfileItem(SigningProfileItem item){ - this.profileItemList.remove( item ); + /** + * @param ordinal If zero, this is an author. If not zero, this is an ordinal number of distributor. + * @return profile item + */ + public SigningProfileItem getProfileItem(int ordinal) { + Assert.isTrue( ordinal >= 0 && ordinal <= MAX_DISTRIBUTOR ); + + return this.profileItemMap.get( ordinal ); } - public List<SigningProfileItem> getProfileItemList() { - return Collections.unmodifiableList( this.profileItemList ); + /** + * @param ordinal If zero, this is an author. If not zero, this is an ordinal number of distributor. + * @return If contains a item, return true. + */ + public boolean containsProfileItem(int ordinal) { + return this.getProfileItem( ordinal ) != null; } - public void setAuthorItem(SigningProfileItem authorItem) { - this.authorItem = authorItem; + /** + * @param ordinal If zero, this is an author. If not zero, this is an ordinal number of distributor. + * @return removed item + */ + public SigningProfileItem removeProfileItem(int ordinal) { + Assert.isTrue( ordinal >= 0 && ordinal <= MAX_DISTRIBUTOR ); + + SigningProfileItem removedItem = this.profileItemMap.remove( ordinal ); + this.profileItemMap.put( ordinal, null ); // mark an empty + + return removedItem; } - public SigningProfileItem getAuthorItem() { - return authorItem; + /** + * Getter for the profile list + * + * @return the profile item list with ordinals. If not set item, the value of its index is null. + */ + public List<SigningProfileItem> getProfileItems() { + final List<SigningProfileItem> result = new ArrayList<SigningProfileItem>(); + + // convert to list + final TreeSet<Integer> keys = new TreeSet<Integer>( this.profileItemMap.keySet() ); + for ( Integer key: keys ) { + result.add( this.profileItemMap.get( key ) ); + } + + return result; } - public SigningProfileItem getDistributorItem(int index) { - int size = this.profileItemList.size(); - if ( index < 0 || index >= size ) { - return null; + public SigningProfileItem getAuthorProfileItem() { + return this.getProfileItem( AUTHOR_ORDINAL ); + } + + public List<SigningProfileItem> getDistributorProfileItems() { + final List<SigningProfileItem> result = new ArrayList<SigningProfileItem>(); + + // convert to list + final TreeSet<Integer> keys = new TreeSet<Integer>( this.profileItemMap.keySet() ); + for ( Integer key: keys ) { + if ( key == AUTHOR_ORDINAL ) { + continue; + } + result.add( this.profileItemMap.get( key ) ); } - return this.profileItemList.get( index ); + return result; } - public void initialize(Collection<? extends SigningProfileItem> itemList) { - this.setAuthorItem( null ); - this.profileItemList.clear(); + /** + * Create a profile item and assign to an ordinal number. + * + * @param ordinal If zero, this is an author. If not zero, this is an ordinal number of distributor. + * @param keyPath a certificate path + * @param password a certificate password + * @param caPath CA of a certificate. + * @param rootCaPath Root CA of a certificate + * @return created profile item + */ + public SigningProfileItem createProfileItem(int ordinal, String keyPath, String password, String caPath, String rootCaPath) { + Assert.isTrue( ordinal >= 0 ); + + // create a profile item safety + SigningProfileItem item = new SigningProfileItem( + ( keyPath == null ) ? StringUtil.EMPTY_STRING : keyPath, // key location + StringUtil.EMPTY_STRING, // identifier + isAuthorOrdinal( ordinal ), // author flag + ( caPath == null ) ? StringUtil.EMPTY_STRING : caPath, // CA location + ( rootCaPath == null ) ? StringUtil.EMPTY_STRING : rootCaPath // Root CA location + ); + + // set the password + if ( ! StringUtil.isEmpty( password ) ) { + item.setPassword( password.toCharArray() ); + } + + // assign a profile item (overwrite) + this.setProfileItem( ordinal, item ); + + return item; + } + + /** + * Read a profile item from the profile item node + * + * @param ordinal + * @param node + * @return + */ + public SigningProfileItem readProfileItem(Node node) { + // check null + if ( !( node instanceof Element ) ) { + return null; + } - for ( SigningProfileItem item : itemList ) { - if ( item.isAuthor() ) { - this.setAuthorItem( item ); + final Element itemElement = (Element) node; + + // get attributes + final String key = itemElement.getAttribute( SignatureConstants.PROFILEITEM_ATTR_KEY ); + final String author = itemElement.getAttribute( SignatureConstants.PROFILEITEM_ATTR_AUTHOR ); + final String distributor = itemElement.getAttribute( SignatureConstants.PROFILEITEM_ATTR_DISTRIBUTOR ); + final String ca = itemElement.getAttribute( SignatureConstants.PROFILEITEM_ATTR_CA ); + final String rootca = itemElement.getAttribute( SignatureConstants.PROFILEITEM_ATTR_ROOTCA ); + String pass = itemElement.getAttribute( SignatureConstants.PROFILEITEM_ATTR_PASS ); + + // decrypt a password. if failed, regard as an original password. + try { + pass = CipherUtil.getDecryptedString( pass ); + // TODO: Organize exceptions + } catch (InvalidKeyException e) { + logger.error("Exception occurred while decrypting signing password", e); + } catch (IllegalBlockSizeException e) { + logger.error("Exception occurred while decrypting signing password", e); + } catch (BadPaddingException e) { + logger.error("Exception occurred while decrypting signing password", e); + } + + // determine ordinal number + int ordinal = 0; + if ( ParsingUtil.parseBoolean( author, false ) ) { // if author is true + ordinal = 0; + } else { // if author is false or nothing, this is a distributor item + int parsedInt = ParsingUtil.parseInt( distributor, NOTHING ); + if ( parsedInt < 0 || parsedInt > MAX_DISTRIBUTOR ) { // if this is not a explicit distributor + ordinal = getEmptyDistributorOrdinal(); // find empty distributor ordinal automatically } else { - this.addProfileItem( item ); + ordinal = parsedInt; + } + if ( ordinal == NOTHING ) { // If full, this is not added. + return null; + } + } + + logger.trace( "item - key :{}, ordinal :{}, ca :{}, rootca :{}, pass {}", new Object[] { key, ordinal, ca, rootca, pass } ); + + return createProfileItem( ordinal, key, pass, ca, rootca ); + } + + public void writeProfileItem(Document doc, Element profileElement, int ordinal) { + Assert.notNull( doc ); + Assert.notNull( profileElement ); + + SigningProfileItem item = this.getProfileItem( ordinal ); + if ( item == null ) { // If nothing, skip + return; + } + + Element element = doc.createElement( SignatureConstants.PROFILEITEM_ELEMENT ); + + XMLUtil.setElementAttribute( doc, SignatureConstants.PROFILEITEM_ATTR_KEY, item.getKeyLocation(), element ); + XMLUtil.setElementAttribute( doc, SignatureConstants.PROFILEITEM_ATTR_CA, item.getCAPath(), element ); + XMLUtil.setElementAttribute( doc, SignatureConstants.PROFILEITEM_ATTR_ROOTCA, item.getRootCAPath(), element ); + + // encrypt password. if failed, write an original password. + String pass = new String( item.getPassword() ); + try { + pass = CipherUtil.getEncryptedString( pass ); + // TODO: Organize exceptions + } catch (InvalidKeyException e) { + logger.error("Exception occurred while encrypting signing password", e); + } catch (IllegalBlockSizeException e) { + logger.error("Exception occurred while encrypting signing password", e); + } catch (BadPaddingException e) { + logger.error("Exception occurred while encrypting signing password", e); + } + XMLUtil.setElementAttribute( doc, SignatureConstants.PROFILEITEM_ATTR_PASS, pass, element ); + + // set author or distributor sequence + XMLUtil.setElementAttribute( doc, SignatureConstants.PROFILEITEM_ATTR_DISTRIBUTOR, Integer.toString( ordinal ), element ); + + profileElement.appendChild( element ); + } + + /** + * Create a profile item for developer and assign to the first distributor information. + * + * @return created profile item + */ + public SigningProfileItem createProfileItemForDeveloper() { + return createProfileItem( + 1, // distributor 1 + SigningPathUtil.getDeveloperKeyPath(), + SigningPathUtil.DISTRIBUTOR1_PWD, + SigningPathUtil.getDeveloperCAPath(), + StringUtil.EMPTY_STRING + ); + } + + public SigningProfileItem createEmptyProfileItem(int ordinal) { + String defaultCAPath = StringUtil.EMPTY_STRING; + if ( isAuthorOrdinal( ordinal ) ) { + defaultCAPath = SigningPathUtil.getAuthorCAPath(); + } + + return createProfileItem( + ordinal, + StringUtil.EMPTY_STRING, + StringUtil.EMPTY_STRING, + defaultCAPath, + StringUtil.EMPTY_STRING + ); + } + + public boolean isAuthorOrdinal(int ordinal) { + return ordinal == AUTHOR_ORDINAL; + } + + /** + * First empty distributor ordinal number getter. + * + * @return If be filled, return NOTHING + */ + public int getEmptyDistributorOrdinal() { + for ( int i = 1; i <= MAX_DISTRIBUTOR; i++ ) { + if ( ! this.containsProfileItem( i ) ) { + return i; + } + } + + return NOTHING; + } + + public int getOrdinal(SigningProfileItem item) { + final TreeSet<Integer> keys = new TreeSet<Integer>( this.profileItemMap.keySet() ); + for ( Integer key: keys ) { + if ( item == this.profileItemMap.get( key ) ) { + return key; } } + + return NOTHING; } } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningProfileContainer.java b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningProfileContainer.java new file mode 100644 index 000000000..f04f78088 --- /dev/null +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/SigningProfileContainer.java @@ -0,0 +1,338 @@ +/* + * Common + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * Jihoon Song <jihoon80.song@samsung.com> + * BonYong Lee <bonyong.lee@samsung.com> + * Kangho Kim <kh5325.kim@samsung.com> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Contributors: + * - S-Core Co., Ltd + * + */ +package org.tizen.common.sign.preferences; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.tizen.common.core.application.InstallPathConfig; +import org.tizen.common.sign.model.SignatureConstants; +import org.tizen.common.sign.util.XMLUtil; +import org.tizen.common.util.Assert; +import org.tizen.common.util.StringUtil; +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + + +public class SigningProfileContainer { + + protected static final Logger logger = LoggerFactory.getLogger( SigningProfileContainer.class ); + + protected final List<SigningProfile> profiles; + protected String activeProfileName; + + + /** + * Constructor + */ + public SigningProfileContainer() { + this.profiles = new ArrayList<SigningProfile>(); + } + + public String getActiveProfileName() { + return this.activeProfileName; + } + + /** + * Default profile getter + * + * @return default profile + */ + public SigningProfile getActiveProfile() { + if ( this.activeProfileName != null ) { + return this.getProfileByName( this.activeProfileName ); + } + + return null; + } + + /** + * Default profile setter. If doesn't contain it, add automatically. + * + * @param defaultProfile If null, regard as the default nothing. + */ + public void setActiveProfile(SigningProfile defaultProfile) { + // If null, don't have a default profile. + if ( defaultProfile == null ) { + this.activeProfileName = null; + return; + } + + this.activeProfileName = defaultProfile.getProfileName(); + + if ( ! this.profiles.contains( defaultProfile ) ) { + addProfile( defaultProfile ); + } + } + + /** + * Profile list getter + * + * @return + */ + public List<SigningProfile> getProfiles() { + return this.profiles; + } + + public boolean containsProfile(String profileName) { + Assert.notNull( profileName ); + + return getProfileByName( profileName ) != null; + } + + public int size() { + return this.profiles.size(); + } + + public SigningProfile getFirstProfile() { + if ( this.profiles.isEmpty() ) { + return null; + } + + return this.profiles.get( 0 ); + } + + public boolean renameProfile(String fromProfileName, String toProfileName) { + Assert.notNull( fromProfileName ); + Assert.notNull( toProfileName ); + + SigningProfile profile = this.getProfileByName( fromProfileName ); + + if ( profile == null ) { + return false; + } + + profile.setProfileName( toProfileName ); + + if ( fromProfileName.equals( this.activeProfileName ) ) { + this.activeProfileName = toProfileName; + } + + return true; + } + + /** + * Profile getter by name + * + * @param profileName + * @return If not found, return null. + */ + public SigningProfile getProfileByName(String profileName) { + Assert.notNull( profileName ); + + for ( SigningProfile profile : getProfiles() ) { + if ( profileName.equals( profile.getProfileName() ) ) { + return profile; + } + } + + return null; + } + + /** + * Add profile to the profile list + * + * @param profile + * @return If be succeeded, return true. + */ + public boolean addProfile(SigningProfile profile) { + Assert.notNull( profile ); + + return this.profiles.add( profile ); + } + + /** + * Remove profile from the profile list. If it is a default profile, will be empty. + * + * @param profile + * @return If be succeeded, return true. + */ + public boolean removeProfile(SigningProfile profile) { + Assert.notNull( profile ); + + if ( profile.getProfileName().equals( this.activeProfileName ) ) { + this.activeProfileName = null; + } + + return this.profiles.remove( profile ); + } + + /** + * Read a profile XML from the input stream + * + * @param in profile file stream + */ + public void readProfileXML( InputStream in ) { + Assert.notNull( in ); + + try { + // read the profile stream. + final Document document = XMLUtil.create( in ); + + // get profile nodes + // TODO: Instead of first child, find the "profiles" element + final Node rootNode = document.getFirstChild(); + if ( !( rootNode instanceof Element ) ) { + return; + } + final Element rootElement = (Element) rootNode; + final String version = rootElement.getAttribute( SignatureConstants.ROOT_ATTR_VER ); // version + + final NodeList profileNodes = rootElement.getElementsByTagName( SignatureConstants.PROFILE_ELEMENT ); + + // use a temporary list for process failure. + final List<SigningProfile> result = new ArrayList<SigningProfile>(); + + for ( int i = 0, n = profileNodes.getLength() ; i < n ; ++i ) { + final Node profileNode = profileNodes.item( i ); + + // create a profile instance + SigningProfile profile = readProfileFromNode( profileNode, version ); + if ( profile != null ) { + result.add(profile); + } + } + + // replace this information + this.profiles.clear(); + for ( SigningProfile profile : result ) { + addProfile( profile ); + } + + // TODO: Organize exceptions + } catch (ParserConfigurationException e) { + logger.error( "Can't parse xml", e ); + } catch (SAXException e) { + logger.error( "Can't parse xml", e ); + } catch (IOException e) { + logger.error( "Can't parse xml", e ); + } + } + + protected SigningProfile readProfileFromNode( Node node, String version ) { + // check null + if ( !( node instanceof Element ) ) { + return null; + } + + final Element profileElement = (Element) node; + final String profileName = profileElement.getAttribute( + SignatureConstants.PROFILE_ATTR_NAME ); // name + + // create a profile + final SigningProfile profile = new SigningProfile( profileName ); + + final NodeList itemNodes = profileElement.getElementsByTagName( + SignatureConstants.PROFILEITEM_ELEMENT ); // profileitem + + if ( StringUtil.isEmpty( version ) ) { + // for loader before 2.2.0 version + profile.createProfileItemForDeveloper(); + } + + for ( int i=0, n = itemNodes.getLength() ; i<n ; ++i ) { + Node item = itemNodes.item( i ); + + // create a profile item + profile.readProfileItem( item ); + } + + return profile; + } + + /** + * Write a profile XML to the output stream + * + * @param out writable profile stream + */ + public void writeProfileXML(OutputStream out) { + Assert.notNull( out ); + + try { + // build the XML document + Document document = XMLUtil.create(); + + Element rootElement = document.createElement( SignatureConstants.ROOT_ELEMENT ); + Attr attr = document.createAttribute( SignatureConstants.ROOT_ATTR_VER ); + attr.setValue( InstallPathConfig.getPlatformVersionNum() ); + rootElement.setAttributeNode( attr ); + + writeProfile( document, rootElement ); + + document.appendChild( rootElement ); + + // write to output stream + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty( OutputKeys.INDENT, "yes" ); + transformer.transform( new DOMSource( document ), new StreamResult( out ) ); + + // TODO: Organize exceptions + } catch (ParserConfigurationException e) { + logger.error( "Can't write a profile", e ); + } catch (TransformerConfigurationException e) { + logger.error( "Can't write a profile", e ); + } catch (TransformerException e) { + logger.error( "Can't write a profile", e ); + } + } + + protected void writeProfile(Document doc, Element rootElement) { + Assert.notNull( doc ); + Assert.notNull( rootElement ); + + for ( SigningProfile profile : this.profiles ) { + // create a profile element with a name attribute + Element profileElement = doc.createElement( SignatureConstants.PROFILE_ELEMENT ); + XMLUtil.setElementAttribute( doc, SignatureConstants.PROFILE_ATTR_NAME, profile.getProfileName(), profileElement ); + + // append profile items + for ( int i = SigningProfile.AUTHOR_ORDINAL; i <= SigningProfile.MAX_DISTRIBUTOR; i++ ) { + profile.writeProfileItem( doc, profileElement, i ); + } + rootElement.appendChild( profileElement ); + } + } +} diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/UIMessages.properties b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/UIMessages.properties index ef5c8029a..00b3708b5 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/preferences/UIMessages.properties +++ b/org.tizen.common.sign/src/org/tizen/common/sign/preferences/UIMessages.properties @@ -3,7 +3,7 @@ org.tizen.common.sign.authorerrordialogtitle=Error generating Author Signature org.tizen.common.sign.distrierrordialogtitle=Error generating Distributor Signature org.tizen.common.sign.authcerterror=Problem generating Author signature. Aborting Author Signature generation. org.tizen.common.sign.checkauthorcertificate=Please check the signing configurations at -org.tizen.common.sign.preference=Preferences > Secure Profiles +org.tizen.common.sign.preference=Preferences > Security Profiles org.tizen.common.sign.profileerrormsg=Active secure profile is not set. Please check the signing configurations at <a>{0}</a>. org.tizen.common.sign.authkeyerror=Problem loading Author private key. Aborting Author Signature generation. org.tizen.common.sign.authcertkeyerror=Problem generating Author Signature. Aborting Author Signature generation. @@ -25,7 +25,7 @@ org.tizen.common.sign.profileitemgrouptitle=Profile Items org.tizen.common.sign.profile.modify=Rename org.tizen.common.sign.profileitem.clear=Clear org.tizen.common.sign.authorsigtitle=Author Certificate -org.tizen.common.sign.distrisigtitle=Distributor Certificate (Optional) +org.tizen.common.sign.distrisigtitle=Distributor Certificate org.tizen.common.sign.certificatevalidityerror=There was an error in certificate validity. Aborting Signature generation. org.tizen.common.sign.certificatevaliditymessage1=The certificate corresponding to org.tizen.common.sign.certificatevaliditymessage2=is not valid.\nThe certificate is not valid before diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/signer/SignatureGenerator.java b/org.tizen.common.sign/src/org/tizen/common/sign/signer/SignatureGenerator.java index ff00420b3..c32e5caff 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/signer/SignatureGenerator.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/signer/SignatureGenerator.java @@ -27,8 +27,6 @@ package org.tizen.common.sign.signer; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import org.eclipse.jface.preference.IPreferenceStore; import org.slf4j.Logger; @@ -38,8 +36,9 @@ import org.tizen.common.TizenPlatformConstants; import org.tizen.common.core.command.ExecutionContext; import org.tizen.common.sign.command.ReadSigningProfileFileCommand; import org.tizen.common.sign.command.SignCommand; +import org.tizen.common.sign.model.SignatureConstants; import org.tizen.common.sign.preferences.Messages; -import org.tizen.common.sign.preferences.SigningPreferencePage; +import org.tizen.common.sign.preferences.SigningProfile; import org.tizen.common.sign.preferences.SigningProfileItem; import org.tizen.common.sign.preferences.UIMessages; import org.tizen.common.sign.util.SigningProfileUtil; @@ -70,28 +69,12 @@ public class SignatureGenerator { this.pStore = SigningProfileUtil.getPreferenceStore(); } - public SigningProfileItem findAuthor(List<SigningProfileItem> profileItems) { - for (SigningProfileItem profileItem : profileItems) { - if ( profileItem.isAuthor() ) { - if ( !StringUtil.isEmpty( profileItem.getKeyLocation() ) ) { - return profileItem; - } - } - } - - return null; - } - - public boolean hasAuthor(List<SigningProfileItem> profileItems) { - return findAuthor( profileItems ) != null; - } - protected boolean getInsertSignatureOption() { return TizenPlatformConstants.SIGNING_DEFAULT; } protected String getActiveProfileName() { - return this.pStore.getString( SigningPreferencePage.defaultProfileKey ); + return this.pStore.getString( SignatureConstants.DEFAULT_PROFILE_KEY ); } /** @@ -101,22 +84,29 @@ public class SignatureGenerator { * @return If profile items are nothing, return a developer profile item only. otherwise, return default profile items with a developer profile item * @throws IOException */ - public List<SigningProfileItem> loadProfiles() throws IOException { - List<SigningProfileItem> profileItems = new ArrayList<SigningProfileItem>(); - - // Always add a developer certificate first because must be "signature1.xml" - profileItems.add( SigningProfileUtil.createDeveloperItem() ); + public SigningProfile loadProfiles() throws IOException { + SigningProfile profile = null; while ( getInsertSignatureOption() ) { // read profiles final ReadSigningProfileFileCommand readProfile = - new ReadSigningProfileFileCommand( SigningProfileUtil.getProfilesPath(), getActiveProfileName() ); + new ReadSigningProfileFileCommand( + SigningProfileUtil.getProfilesPath().toPortableString(), + getActiveProfileName() ); CommonPlugin.getDefault().getExecutor().execute( readProfile ); - // check requirements in profile - if ( hasAuthor( readProfile.getProfileItems() ) ) { - profileItems.addAll( readProfile.getProfileItems() ); - break; + profile = readProfile.getProfile(); + + if ( profile != null ) { + // check requirements in profile + SigningProfileItem authorItem = profile.getProfileItem( SigningProfile.AUTHOR_ORDINAL ); + SigningProfileItem dist1Item = profile.getProfileItem( 1 ); + if ( authorItem != null && dist1Item != null ) { + if ( ! StringUtil.isEmpty( authorItem.getKeyLocation() ) + && ! StringUtil.isEmpty( dist1Item.getKeyLocation() ) ) { + break; + } + } } // interact user for setting profiles @@ -127,11 +117,11 @@ public class SignatureGenerator { // retry reading } - return profileItems; + return profile; } - public void sign(String path, List<SigningProfileItem> profileItems) { - final SignCommand command = new SignCommand( path, getActiveProfileName(), profileItems, isRDSMode() ); + public void sign(String path, SigningProfile profile) { + final SignCommand command = new SignCommand( path, profile, isRDSMode() ); command.setExcludes( new String[] { ".*", "*~" } ); CommonPlugin.getDefault().getExecutor().execute( this.newCtx, command ); } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/ui/CertGenerationDialog.java b/org.tizen.common.sign/src/org/tizen/common/sign/ui/CertGenerationDialog.java new file mode 100644 index 000000000..5eda32c2c --- /dev/null +++ b/org.tizen.common.sign/src/org/tizen/common/sign/ui/CertGenerationDialog.java @@ -0,0 +1,170 @@ +package org.tizen.common.sign.ui; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.dialogs.StatusDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.tizen.common.sign.Activator; +import org.tizen.common.util.Assert; +import org.tizen.common.util.StringUtil; +import org.tizen.common.util.ValidationUtil; + + +public class CertGenerationDialog extends StatusDialog { + + public enum CertDataKey { + KeyName( "Key filename", true ), + Alias( "Alias", true ), + Password( "Password", true ), + ConfirmPW( "Password confirmation", true ), + Country( "Country (two letters)", false ), + State( "State", false ), + City( "City", false ), + Organization( "Organization", false ), + Department( "Department", false ), + Name( "Name", false ), + Email( "E-mail", false ); + + private String title; + private boolean required; + + CertDataKey(String title, boolean required) { + this.title = title; + this.required = required; + } + + public String getTitle() { + return ( getRequired() ) ? this.title + " (*)" : this.title; + } + + public boolean getRequired() { + return this.required; + } + } + + protected int minimumWidth = 400; + + protected Map<CertDataKey, String> data = new HashMap<CertDataKey, String>(); + + + /** + * Constructor + * + * @param parent + */ + public CertGenerationDialog(Shell parent) { + super( parent ); + + this.setTitle( "Certificate Generator" ); + this.setHelpAvailable( false ); + } + + public String getValue(CertDataKey key) { + Assert.notNull( key ); + + return this.data.get( key ); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea( parent ); + GridData gridData = (GridData) composite.getLayoutData(); + gridData.minimumWidth = this.minimumWidth; + gridData.widthHint = this.minimumWidth; + + for ( CertDataKey key : CertDataKey.values() ) { + boolean bPassword = ( key == CertDataKey.Password ) || ( key == CertDataKey.ConfirmPW ); + createText( composite, key, bPassword ); + } + + validateDialog(); + + return composite; + } + + protected Composite createText(Composite parent, final CertDataKey key, boolean bPassword) { + final Composite composite = new Composite( parent, SWT.NONE ); + composite.setLayout( new GridLayout( 2, true ) ); + composite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); + + Label label = new Label( composite, SWT.NONE ); + label.setText( key.getTitle() ); + label.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); +// if ( key.getRequired() ) { +// label.setFont( JFaceResources.getFontRegistry().getBold( JFaceResources.DIALOG_FONT ) ); +// } + + int style = SWT.SINGLE | SWT.BORDER; + if ( bPassword ) { + style |= SWT.PASSWORD; + } + + final Text text = new Text( composite, style ); + GridData textLayoutData = new GridData( GridData.FILL_HORIZONTAL ); +// textLayoutData.horizontalSpan = 2; + text.setLayoutData( textLayoutData ); + text.setText( StringUtil.EMPTY_STRING ); + text.addModifyListener( new ModifyListener() { + @Override + public void modifyText(ModifyEvent modifyevent) { + data.put( key, text.getText() ); + + validateDialog(); + } + } ); + + return composite; + } + + protected void validateDialog() { + // must not empty + for( CertDataKey key : CertDataKey.values() ) { + if ( key.getRequired() ) { + String value = this.data.get( key ); + if ( StringUtil.isEmpty( value) ) { + updateErrorStatus( key.getTitle() + " is empty." ); + return; + } + } + } + + // both a password and a confirm must equal + String password = this.data.get( CertDataKey.Password ); + String confirm = this.data.get( CertDataKey.ConfirmPW ); + if ( ! password.equals( confirm ) ) { + updateErrorStatus( "The password and confirmation don't match." ); + return; + } + + // email validate + String email = this.data.get( CertDataKey.Email ); + if ( ! StringUtil.isEmpty( email ) ) { + if ( ! ValidationUtil.checkForEmail( email ) ) { + updateErrorStatus( "E-mail address is malformed" ); + return; + } + } + + updateOKStatus(); + } + + private void updateErrorStatus(String msg) { + updateStatus( new Status( IStatus.ERROR, Activator.PLUGIN_ID, msg ) ); + } + + private void updateOKStatus() { + updateStatus( new Status( IStatus.OK, Activator.PLUGIN_ID, StringUtil.EMPTY_STRING ) ); + } +} diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/ui/ProfileItemDialog.java b/org.tizen.common.sign/src/org/tizen/common/sign/ui/ProfileItemDialog.java new file mode 100644 index 000000000..3922bebba --- /dev/null +++ b/org.tizen.common.sign/src/org/tizen/common/sign/ui/ProfileItemDialog.java @@ -0,0 +1,203 @@ +package org.tizen.common.sign.ui; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.dialogs.StatusDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.tizen.common.sign.preferences.Messages; +import org.tizen.common.sign.preferences.SigningProfileItem; +import org.tizen.common.util.Assert; +import org.tizen.common.util.StringUtil; + + +public class ProfileItemDialog extends StatusDialog { + + protected final String[] filterExt_p12 = new String[] { "*.p12" }; + protected final String[] filterExt_cer = new String[] { "*.cer" }; + + private enum ItemDataKey { + keyPath( "Certificate Path", true ), + password( "Password", true ), + caPath( "CA Path", false ), + rootCaPath( "Root CA Path", false ); + + private String title; + private boolean required; + + ItemDataKey(String title, boolean required) { + this.title = title; + this.required = required; + } + + public String getTitle() { + return ( getRequired() ) ? this.title + " (*)" : this.title; + } + + public boolean getRequired() { + return this.required; + } + } + + protected int minimumWidth = 600; + + protected Map<ItemDataKey, String> data = new HashMap<ItemDataKey, String>(); + + protected boolean bEnableCA; + protected SigningProfileItem item; + + + /** + * Constructor + * + * @param parent + * @param item SigningProfileItem for initial data + */ + public ProfileItemDialog(Shell parent, SigningProfileItem item) { + super( parent ); + + this.setTitle( "Certificate Editor" ); + this.setHelpAvailable( false ); + + Assert.notNull( item ); + + this.item = item; + + this.data.put( ItemDataKey.keyPath, item.getKeyLocation() ); + this.data.put( ItemDataKey.password, new String( item.getPassword() ) ); + this.data.put( ItemDataKey.caPath, item.getCAPath() ); + this.data.put( ItemDataKey.rootCaPath, item.getRootCAPath() ); + + this.bEnableCA = ! item.isAuthor(); + } + + public String getKeyPath() { + return this.data.get( ItemDataKey.keyPath ); + } + + public char[] getPassword() { + return this.data.get( ItemDataKey.password ).toCharArray(); + } + + public String getCaPath() { + return this.data.get( ItemDataKey.caPath ); + } + + public String getRootPath() { + return this.data.get( ItemDataKey.rootCaPath ); + } + + @Override + protected Control createDialogArea(Composite parent) { + Composite composite = (Composite) super.createDialogArea( parent ); + GridData gridData = (GridData) composite.getLayoutData(); + gridData.minimumWidth = this.minimumWidth; + gridData.widthHint = this.minimumWidth; + + createTextWithBrowse( composite, ItemDataKey.keyPath, filterExt_p12, true ); + createPasswordText( composite, ItemDataKey.password ); + createTextWithBrowse( composite, ItemDataKey.caPath, filterExt_cer, this.bEnableCA ); + createTextWithBrowse( composite, ItemDataKey.rootCaPath, filterExt_cer, this.bEnableCA ); + + return composite; + } + + protected Composite createPasswordText(Composite parent, final ItemDataKey key) { + final Composite composite = new Composite( parent, SWT.NONE ); + composite.setLayout( new GridLayout( 3, false ) ); + composite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); + + Label label = new Label( composite, SWT.NONE ); + label.setText( key.getTitle() ); + GridData labelLayoutData = new GridData(); + labelLayoutData.horizontalSpan = 3; + label.setLayoutData( labelLayoutData ); +// if ( key.getRequired() ) { +// label.setFont( JFaceResources.getFontRegistry().getBold( JFaceResources.DIALOG_FONT ) ); +// } + + final Text text = new Text( composite, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD ); + GridData textLayoutData = new GridData( GridData.FILL_HORIZONTAL ); + textLayoutData.horizontalSpan = 2; + text.setLayoutData( textLayoutData ); + text.setText( this.data.get( key ) ); + text.addModifyListener( new ModifyListener() { + @Override + public void modifyText(ModifyEvent modifyevent) { + data.put( key, text.getText() ); + } + } ); + + return composite; + } + + protected Composite createTextWithBrowse(Composite parent, final ItemDataKey key, final String[] filterExtension, boolean bEnable ) { + final Composite composite = new Composite( parent, SWT.NONE ); + composite.setLayout( new GridLayout( 3, false ) ); + composite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ) ); + + Label label = new Label( composite, SWT.NONE ); + label.setText( key.getTitle() ); + GridData labelLayoutData = new GridData(); + labelLayoutData.horizontalSpan = 3; + label.setLayoutData( labelLayoutData ); +// if ( key.getRequired() ) { +// label.setFont( JFaceResources.getFontRegistry().getBold( JFaceResources.DIALOG_FONT ) ); +// } + + final Text text = new Text( composite, SWT.SINGLE | SWT.BORDER ); + GridData textLayoutData = new GridData( GridData.FILL_HORIZONTAL ); + textLayoutData.horizontalSpan = 2; + text.setLayoutData( textLayoutData ); + text.setText( this.data.get( key ) ); + text.addModifyListener( new ModifyListener() { + @Override + public void modifyText(ModifyEvent modifyevent) { + data.put( key, text.getText() ); + } + } ); + text.setEnabled( bEnable ); + + Button browseButton = new Button( composite, SWT.PUSH ); + browseButton.setText( "Browse..." ); + browseButton.setLayoutData( new GridData() ); + browseButton.addSelectionListener( new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + String value = handleBrowseButtonPressed( composite, filterExtension, data.get( key ) ); + + if ( value != null ) { + text.setText( value ); + } + } + } ); + browseButton.setEnabled( bEnable ); + + return composite; + } + + protected String handleBrowseButtonPressed(Composite parent, String[] filterExtensions, String initialFileName) { + FileDialog dialog = new FileDialog( parent.getShell(), SWT.NONE ); + dialog.setFilterExtensions( filterExtensions ); + dialog.setText( Messages.FileBrowserCellEditor_2 ); + + if ( ! StringUtil.isEmpty( initialFileName ) ) { + dialog.setFileName( initialFileName ); + } + + return dialog.open(); + } +} diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/ui/TizenSigningDialog.java b/org.tizen.common.sign/src/org/tizen/common/sign/ui/TizenSigningDialog.java deleted file mode 100644 index bbd1e7795..000000000 --- a/org.tizen.common.sign/src/org/tizen/common/sign/ui/TizenSigningDialog.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Common -* -* Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. -* -* Contact: -* NamKoong Ho <ho.namkoong@samsung.com> -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -* -* Contributors: -* - S-Core Co., Ltd -* -*/ - -package org.tizen.common.sign.ui; - -import java.util.List; - -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.window.ApplicationWindow; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; -import org.tizen.common.sign.preferences.SigningProfile; -import org.tizen.common.sign.preferences.SigningProfileItem; -import org.tizen.common.sign.util.SigningProfileUtil; -import org.tizen.common.util.SWTUtil; -import org.tizen.common.util.StringUtil; - -public class TizenSigningDialog extends ApplicationWindow{ - - private final int GROUP_WIDTH = 500; - private final int GROUP_HEIGHT= 150; - private final int BUTTON_WIDTH = 70; - private boolean closedByOk = false; - private final ModifyListener callValidateDialogListener = new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - if(validateDialog()) { - okButton.setEnabled(true); - } - else { - okButton.setEnabled(false); - } - } - }; - private Text messageLabel; - private Text authorPassText ; - private Text distPassText; - private Button okButton; - private Button saveAuthorPassButton; - private Button saveDistPassButton; - - private String authorPass; - private String distPass; - private boolean isDistEnabled = false; - private boolean open = false; - - private List<SigningProfile> profileList; - private SigningProfile defaultProfile; - private SigningProfileItem distProfile; - private SigningProfileItem authorProfile; - - public TizenSigningDialog(Shell parentShell, List<SigningProfile> profileList) { - super(parentShell); - - this.distPass = ""; - this.authorPass = ""; - this.profileList = profileList; - this.defaultProfile = SigningProfileUtil.getDefaultProfile(profileList); - this.authorProfile = this.defaultProfile.getAuthorItem(); - char[] _authorPass = this.authorProfile.getPassword(); - if(_authorPass.length == 0) { - this.authorPass = ""; - this.open = true; - } - else { - this.authorPass = new String(_authorPass); - } - - List<SigningProfileItem> distProfileList = this.defaultProfile.getProfileItemList(); - if(distProfileList.size() > 0) { - this.distProfile = distProfileList.get(0); - if(!StringUtil.isEmpty(distProfile.getKeyLocation())) { - this.isDistEnabled = true; - char[] _distPass = this.distProfile.getPassword(); - if(_distPass.length == 0) { - this.distPass = ""; - this.open = true; - } - else { - this.distPass = new String(_distPass); - } - } - } - else { - this.distPass = ""; - } - } - - public boolean isClosedByOk() { - return closedByOk; - } - - public boolean isDistEnabled() { - return isDistEnabled; - } - - public boolean isOpen() { - return open; - } - - protected boolean validateDialog() { - - String authorPass = this.authorPassText.getText(); - if("".equals(authorPass)) { - setMessage(Messages.TizenSigningDIalog_messageAuthorPassEmpty); - return false; - } - - if(isDistEnabled) { - String distPass = this.distPassText.getText(); - if("".equals(distPass)) { - setMessage(Messages.TizenSigningDIalog_messageDistPassEmpty); - return false; - } - } - - - setMessage(null); - return true; - } - - @Override - protected int getShellStyle() { - int style = super.getShellStyle(); - style = style | SWT.APPLICATION_MODAL; - return style; - } - - private void setMessage(String message) { - if(message == null) { - this.messageLabel.setText(""); - return; - } - this.messageLabel.setText(message); - } - - @Override - protected Control createContents(Composite parent) { - Composite mainComposite = new Composite(parent, SWT.NONE); - - GridLayout layout = new GridLayout(); - layout.numColumns = 1; - layout.marginWidth = 0; - layout.marginHeight = 0; - layout.marginLeft = 5; - layout.marginRight = 5; - layout.marginTop = 5; - layout.marginBottom = 5; - mainComposite.setLayout(layout); - SWTUtil.setGridLayoutData(mainComposite, 700, -1, -1, -1, SWT.NONE); - createMessageText(mainComposite); - createPassGroup(mainComposite); - createButtons(mainComposite); - this.getShell().setText(Messages.TizenSigningDialog_title); - addListeners(); - - if(validateDialog()) { - okButton.setEnabled(true); - } - - authorPassText.setFocus(); - this.getShell().setDefaultButton(okButton); - - return mainComposite; - } - - private void createMessageText(Composite mainComposite) { - Color whiteColor = SWTUtil.getDisplay().getSystemColor(SWT.COLOR_WHITE); - - Composite msgComposite = new Composite(mainComposite, SWT.None); - GridLayout msgCompositeLayout = new GridLayout(); - msgCompositeLayout.numColumns = 1; - msgCompositeLayout.makeColumnsEqualWidth = false; - msgCompositeLayout.marginBottom = 0; - msgCompositeLayout.marginHeight = 0; - msgCompositeLayout.marginLeft = 0; - msgCompositeLayout.marginRight = 0; - msgCompositeLayout.marginTop = 0; - msgCompositeLayout.marginWidth = 0; - SWTUtil.setGridLayoutData(msgComposite, -1, -1, -1, -1, GridData.FILL_BOTH); - msgComposite.setLayout(msgCompositeLayout); - msgComposite.setBackground(whiteColor); - Label titleLabel = new Label(msgComposite, SWT.LEFT); - titleLabel.setBackground(whiteColor); - titleLabel.setFont(JFaceResources.getBannerFont()); - titleLabel.setText(Messages.TizenSigningDIalog_messageFirst); - SWTUtil.setGridLayoutData(titleLabel, -1, -1, -1, -1, GridData.FILL_BOTH); - - messageLabel = new Text(msgComposite, SWT.WRAP | SWT.READ_ONLY); - messageLabel.setText(" \n "); // two lines//$NON-NLS-1$ - messageLabel.setFont(JFaceResources.getDialogFont()); - messageLabel.setBackground(whiteColor); - SWTUtil.setGridLayoutData(messageLabel, -1, -1, -1, -1, GridData.FILL_BOTH); - } - - private void addListeners() { - this.authorPassText.addModifyListener(this.callValidateDialogListener); - this.distPassText.addModifyListener(this.callValidateDialogListener); - - okButton.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - performOk(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - } - - private void createButtons(Composite parent) { - Composite buttonComposite = new Composite(parent, SWT.None); - GridLayout buttonComositeLayout = new GridLayout(); - buttonComositeLayout.numColumns = 3; - buttonComositeLayout.makeColumnsEqualWidth = false; - buttonComposite.setLayout(buttonComositeLayout); - SWTUtil.setGridLayoutData(buttonComposite, -1, -1, -1, -1, GridData.FILL_HORIZONTAL); - - Label emptyLabel = new Label(buttonComposite, SWT.None); - SWTUtil.setGridLayoutData(emptyLabel, -1, -1, -1, -1, GridData.FILL_HORIZONTAL); - - Button cancelButton = new Button(buttonComposite, SWT.PUSH | SWT.CENTER); - cancelButton.setText("Cancel"); - SWTUtil.setGridLayoutData(cancelButton, -1, BUTTON_WIDTH, -1, -1, SWT.NONE); - cancelButton.addSelectionListener(new SelectionListener() { - - @Override - public void widgetSelected(SelectionEvent e) { - close(); - } - - @Override - public void widgetDefaultSelected(SelectionEvent e) { - } - }); - - okButton = new Button(buttonComposite, SWT.PUSH | SWT.CENTER); - okButton.setText("OK"); - SWTUtil.setGridLayoutData(okButton, -1, BUTTON_WIDTH, -1, -1, SWT.NONE); - okButton.setEnabled(false); - } - - private void createPassGroup(Composite parent) { - final Composite passComposite = new Composite(parent, SWT.NONE); - GridLayout authorGroupLayout = new GridLayout(); - authorGroupLayout.numColumns = 2; - authorGroupLayout.makeColumnsEqualWidth = false; - passComposite.setLayout(authorGroupLayout); - - SWTUtil.setGridLayoutData(passComposite, GROUP_HEIGHT, GROUP_WIDTH, -1, -1, GridData.FILL_BOTH); - - Label authorPassLabel = new Label(passComposite, SWT.None); - authorPassLabel.setText(Messages.TizenSigningDIalog_authorPassLabel); - authorPassLabel.setToolTipText(Messages.TizenSigningDIalog_authorPassTooltip); - - authorPassText = new Text(passComposite, SWT.BORDER | SWT.PASSWORD); - SWTUtil.setGridLayoutData(authorPassText, -1, -1, -1, -1, GridData.FILL_HORIZONTAL); - authorPassText.setText(this.authorPass); - - saveAuthorPassButton = new Button(passComposite, SWT.CHECK); - - this.saveAuthorPassButton.setSelection(false); - SWTUtil.setGridLayoutData(saveAuthorPassButton, -1, -1, 2, -1, SWT.None); - saveAuthorPassButton.setText("Save author password"); - - Label distPassLabel = new Label(passComposite, SWT.None); - distPassLabel.setText(Messages.TizenSigningDIalog_distPassLabel); - distPassLabel.setToolTipText(Messages.TizenSigningDIalog_distPassTooltip); - - distPassText = new Text(passComposite, SWT.BORDER | SWT.PASSWORD); - SWTUtil.setGridLayoutData(distPassText, -1, -1, -1, -1, GridData.FILL_HORIZONTAL); - distPassText.setText(this.distPass); - - saveDistPassButton = new Button(passComposite, SWT.CHECK); - this.saveDistPassButton.setSelection(false); - SWTUtil.setGridLayoutData(saveDistPassButton, -1, -1, 2, -1, SWT.None); - saveDistPassButton.setText("Save distributor password"); - - if(!isDistEnabled) { - distPassText.setEnabled(false); - saveDistPassButton.setEnabled(false); - distPassLabel.setEnabled(false); - } - } - - private void performOk() { - - if(!validateDialog()) { - return; - } - - boolean save = false; - this.distPass = this.distPassText.getText(); - this.authorPass = this.authorPassText.getText(); - - if(this.saveAuthorPassButton.getSelection()) { - this.authorProfile.setPassword(this.authorPassText.getTextChars()); - save = true; - } - if(this.saveDistPassButton.getSelection()) { - this.distProfile.setPassword(this.distPassText.getTextChars()); - save = true; - } - - if(save) { - SigningProfileUtil.writeProfilesAndProfileItems(profileList); - } - - this.closedByOk = true; - this.close(); - } - - public String getAuthorPass() { - return this.authorPass; - } - - public String getDistPass() { - return this.distPass; - } -} diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/util/SigningProfileUtil.java b/org.tizen.common.sign/src/org/tizen/common/sign/util/SigningProfileUtil.java index 419e66065..d5357344d 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/util/SigningProfileUtil.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/util/SigningProfileUtil.java @@ -24,542 +24,106 @@ */ package org.tizen.common.sign.util; -import static org.tizen.common.util.StringUtil.isEmpty; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.IOException; import java.io.InputStream; -import java.security.InvalidKeyException; -import java.util.ArrayList; -import java.util.List; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.eclipse.jface.preference.IPreferenceStore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.tizen.common.core.application.InstallPathConfig; import org.tizen.common.sign.Activator; -import org.tizen.common.sign.preferences.SigningPreferencePage; -import org.tizen.common.sign.preferences.SigningProfile; -import org.tizen.common.sign.preferences.SigningProfileItem; -import org.tizen.common.util.Assert; -import org.tizen.common.util.CipherUtil; +import org.tizen.common.sign.model.SignatureConstants; +import org.tizen.common.sign.preferences.SigningProfileContainer; import org.tizen.common.util.IOUtil; -import org.tizen.common.util.ObjectUtil; -import org.tizen.common.util.ParsingUtil; import org.tizen.common.util.StringUtil; -import org.w3c.dom.Attr; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; + public class SigningProfileUtil { - protected static final String PROFILE_ATTR_NAME = "name"; //$NON-NLS-1$ - - protected static final String ELEMENT_PROFILE = "profile"; //$NON-NLS-1$ - protected static final String PROFILE_ELEMENT_ITEM = "profileitem"; //$NON-NLS-1$ - - public static final String ITEM_ATTR_KEY = "key"; //$NON-NLS-1$ - public static final String ITEM_ATTR_AUTHOR = "author"; //$NON-NLS-1$ - public static final String ITEM_ATTR_CA = "ca"; //$NON-NLS-1$ - public static final String ITEM_ATTR_ROOTCA = "rootca"; //$NON-NLS-1$ - public static final String ITEM_ATTR_PASS = "password"; - - protected static final String PROFILES_FILE = "profiles.xml"; //$NON-NLS-1$ - - protected static final Logger logger = LoggerFactory.getLogger( SigningProfileUtil.class ); - - public static SigningProfileItem createDeveloperItem() throws IOException { - final SigningProfileItem profileItem = new SigningProfileItem(); - - profileItem.setKeyLocation( getDeveloperKeyPath() ); - profileItem.setPassword( SigningPathUtil.DISTRIBUTOR1_PWD.toCharArray() ); - profileItem.setIdentifier( StringUtil.EMPTY_STRING ); //$NON-NLS-1$ - profileItem.setAuthor( false ); - profileItem.setCAPath( SigningProfileUtil.getDeveloperCAPath() ); - profileItem.setRootCAPath( StringUtil.EMPTY_STRING ); - - return profileItem; - } - - protected static SigningProfileItem createItem( Node node ) - { - if ( !(node instanceof Element ) ) - { - return null; - } - - final SigningProfileItem profileItem = new SigningProfileItem(); - - final Element itemElement = (Element) node; - - final String key = itemElement.getAttribute( ITEM_ATTR_KEY ); - final String author = itemElement.getAttribute( ITEM_ATTR_AUTHOR ); - final String ca = itemElement.getAttribute( ITEM_ATTR_CA ); - final String rootca = itemElement.getAttribute( ITEM_ATTR_ROOTCA ); - String tempPass = itemElement.getAttribute(ITEM_ATTR_PASS); - try { - tempPass = CipherUtil.getDecryptedString(tempPass); - } - catch ( Exception e) - { - logger.error("Exception occurred while decrypting signing password", e); - } - - final String pass = tempPass; - logger.trace( "item - key :{}, author :{}, ca :{}, rootca :{}, pass {}", new Object[] { key, author, ca, rootca, pass} ); - - profileItem.setKeyLocation( key ); - profileItem.setAuthor( ParsingUtil.parseBoolean( author, false ) ); - profileItem.setCAPath( ca ); - profileItem.setRootCAPath( rootca ); - profileItem.setPassword( pass.toCharArray() ); - - return profileItem; - } - - protected static SigningProfile create( final Node node ) - { - if ( !( node instanceof Element ) ) - { - return null; - } - - final SigningProfile profile = new SigningProfile(); - final Element profileElement = (Element) node; - - final String profileName = profileElement.getAttribute( PROFILE_ATTR_NAME ); - profile.setProfileName( profileName ); - - final NodeList itemNodes = profileElement.getElementsByTagName( PROFILE_ELEMENT_ITEM ); - for ( int i=0, n = itemNodes.getLength() ; i<n ; ++i ) - { - - final SigningProfileItem item = createItem( itemNodes.item( i ) ); - - if ( null == item ) - { - continue; - } - else if ( item.isAuthor() ) - { - profile.setAuthorItem( item ); - } - else - { - profile.addProfileItem( item ); - } - } - - return profile; - } - - public static List<SigningProfile> populateProfiles( final InputStream in ) - { - final List<SigningProfile> ret = new ArrayList<SigningProfile>(); - - try { - final Document document = XMLUtil.create( in ); - final Node rootNode = document.getFirstChild(); - - if ( !( rootNode instanceof Element ) ) - { - return ret; - } - - final Element rootElement = (Element) rootNode; - final NodeList profileNodes = rootElement.getElementsByTagName( ELEMENT_PROFILE ); - for ( int i = 0, n = profileNodes.getLength() ; i < n ; ++i ) - { - final Node profileNode = profileNodes.item( i ); - - SigningProfile profile = create( profileNode ); - if ( null == profile ) - { - continue; - } - ret.add(profile); - } - } catch (ParserConfigurationException e) { - logger.error( "Can't parse xml", e ); - } catch (SAXException e) { - logger.error( "Can't parse xml", e ); - } catch (IOException e) { - logger.error( "Can't parse xml", e ); - } - return ret; - } - - public static SigningProfile extractProfile( final InputStream in, final String profileName ) - { - if ( isEmpty( profileName ) ) - { - return null; - } - - try { - final Document document = XMLUtil.create( in ); - final Node rootNode = document.getFirstChild(); - - if ( !( rootNode instanceof Element ) ) - { - return null; - } - - final Element rootElement = (Element) rootNode; - final NodeList profileNodes = rootElement.getElementsByTagName( ELEMENT_PROFILE ); - for ( int i = 0, n = profileNodes.getLength() ; i < n ; ++i ) - { - final Node profileNode = profileNodes.item( i ); - - final SigningProfile profile = create( profileNode ); - if ( null == profile ) - { - continue; - } - if ( ObjectUtil.equals( profileName, profile.getProfileName()) ) - { - return profile; - } - } - } catch (ParserConfigurationException e) { - logger.error( "Can't parse xml", e ); - } catch (SAXException e) { - logger.error( "Can't parse xml", e ); - } catch (IOException e) { - logger.error( "Can't parse xml", e ); - } - return null; - } - + protected static final Logger logger = LoggerFactory.getLogger( SigningProfileUtil.class ); - public static InputStream openProfileFile( File file ) - { - try { - if (!file.exists()) { - return null; - } - - return new FileInputStream( file ); - } - catch ( final IllegalStateException e) - { - logger.error( "Can't access state location", e ); - } - catch ( final FileNotFoundException e ) - { - logger.debug( "Can't open profile", e ); - } - - return null; - } - - public static List<SigningProfileItem> parseProfileFile( final InputStream in, final String profileName ) - { - final ArrayList<SigningProfileItem> ret = new ArrayList<SigningProfileItem>(); - if ( null == in ) - { - return ret; - } - - final SigningProfile profile = SigningProfileUtil.extractProfile( in, profileName ); - if ( null == profile ) - { - return ret; - } - if ( null != profile.getAuthorItem() ) - { - ret.add( profile.getAuthorItem() ); - } - ret.addAll( profile.getProfileItemList() ); - return ret; - } - - public static IPreferenceStore getPreferenceStore() { - return Activator.getDefault().getPreferenceStore(); - } - - public static String getProfilesPath() { - IPath location = Activator.getDefault().getStateLocation().append( PROFILES_FILE ); - return location.toPortableString(); - } + protected static final String PROFILES_FILE = "profiles.xml"; //$NON-NLS-1$ - public static void writeProfilesAndProfileItems(List<SigningProfile> profileList) { - IPath location = Activator.getDefault().getStateLocation(); - IPath xmlFiePath = location.append("profiles.xml"); //$NON-NLS-1$ - File file = new File(xmlFiePath.toOSString()); - - DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder; + public static SigningProfileContainer getProfileContainerFromFile() { + SigningProfileContainer container = new SigningProfileContainer(); + + // read a profile file + IPath profilesPath = getProfilesPath(); + InputStream inputStream = null; try { - documentBuilder = documentBuilderFactory.newDocumentBuilder(); - Document document = documentBuilder.newDocument(); - Element profilesElement = document.createElement("profiles"); //$NON-NLS-1$ - - for (SigningProfile profile : profileList) { - Element profileElement = document.createElement("profile"); //$NON-NLS-1$ - Attr attribute = document.createAttribute("name"); //$NON-NLS-1$ - attribute.setNodeValue(profile.getProfileName()); - profileElement.setAttributeNode(attribute); - if (profile.getAuthorItem() != null) { - SigningProfileItem authorItem = profile.getAuthorItem(); - profileElement.appendChild(createSigningProfileItem(document, authorItem, "true")); - } - List<SigningProfileItem> profileItemList = profile.getProfileItemList(); - for (SigningProfileItem profileItem : profileItemList) { - profileElement.appendChild(createSigningProfileItem(document, profileItem, new Boolean(profileItem.isAuthor()).toString())); - } - - profilesElement.appendChild(profileElement); - } + inputStream = openFileStream( profilesPath.toFile() ); - document.appendChild(profilesElement); - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer; - try { - transformer = transformerFactory.newTransformer(); - DOMSource source = new DOMSource(document); - StreamResult result = new StreamResult(new FileOutputStream(file.getPath())); - transformer.transform(source, result); - } catch (TransformerConfigurationException e) { - logger.error( "Can't write a profile", e ); - } catch (TransformerException e) { - logger.error( "Can't write a profile", e ); + if ( inputStream != null ) { + container.readProfileXML( inputStream ); } - IFile xmlFile = ResourcesPlugin.getWorkspace().getRoot().getFile(location); - xmlFile.refreshLocal(IResource.DEPTH_INFINITE, null); - } - catch ( final ParserConfigurationException e ) - { - logger.error( "Can't write a profile", e ); - } - catch ( final FileNotFoundException e ) - { - logger.error( "Can't write a profile", e ); - } - catch ( final Exception e ) - { - logger.error( "Can't write a profile", e ); - } - } - - private static Element createSigningProfileItem(Document document, SigningProfileItem item, String author) { - Element profileItemElement = document.createElement("profileitem"); //$NON-NLS-1$ - Attr keyAttr = document.createAttribute(SigningProfileUtil.ITEM_ATTR_KEY); //$NON-NLS-1$ - keyAttr.setNodeValue(item.getKeyLocation()); - Attr caAttr = document.createAttribute(SigningProfileUtil.ITEM_ATTR_CA); - caAttr.setNodeValue(item.getCAPath()); - Attr rootCaAttr = document.createAttribute(SigningProfileUtil.ITEM_ATTR_ROOTCA); - rootCaAttr.setNodeValue(item.getRootCAPath()); - Attr passAttr = document.createAttribute(SigningProfileUtil.ITEM_ATTR_PASS); - String pass = new String(item.getPassword()); - try { - pass = CipherUtil.getEncryptedString(pass); - } - catch ( final InvalidKeyException e ) - { - logger.error("Exception occurred while encrypting signing password", e); - } - catch ( final IllegalBlockSizeException e ) - { - logger.error("Exception occurred while encrypting signing password", e); - } - catch ( final BadPaddingException e ) - { - logger.error("Exception occurred while encrypting signing password", e); + } finally { + IOUtil.tryClose( inputStream ); } - passAttr.setNodeValue(pass); - Attr authorAttr = document.createAttribute(SigningProfileUtil.ITEM_ATTR_AUTHOR); //$NON-NLS-1$ - authorAttr.setNodeValue(author); //$NON-NLS-1$ - profileItemElement.setAttributeNode(keyAttr); - profileItemElement.setAttributeNode(authorAttr); - profileItemElement.setAttributeNode(caAttr); - profileItemElement.setAttributeNode(rootCaAttr); - profileItemElement.setAttributeNode(passAttr); - return profileItemElement; + + return container; } - public static List<SigningProfile> populateProfiles() { - - List<SigningProfile> profileList = new ArrayList<SigningProfile>(); - IPath location = Activator.getDefault().getStateLocation(); - IPath filePath = location.append("profiles.xml"); //$NON-NLS-1$ - File file = new File(filePath.toOSString()); - - if (!file.exists()) { - return profileList; - } - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder; + public static InputStream openFileStream( File file ) { try { - builder = factory.newDocumentBuilder(); - Document document = builder.parse(file); - Node rootNode = document.getFirstChild(); - - if (rootNode != null && rootNode instanceof Element) { - Element rootElement = (Element) rootNode; - NodeList profileNodes = rootElement.getElementsByTagName("profile"); //$NON-NLS-1$ - for (int i = 0; i < profileNodes.getLength(); i++) { - Node profileNode = profileNodes.item(i); - if (profileNode instanceof Element) { - SigningProfile profile = new SigningProfile(); - Element profileElement = (Element) profileNode; - String profileName = profileElement.getAttribute("name"); //$NON-NLS-1$ - profile.setProfileName(profileName); - NodeList profileItemNodes = profileElement.getElementsByTagName("profileitem"); //$NON-NLS-1$ - for (int j = 0; j < profileItemNodes.getLength(); j++) { - Node profileItemNode = profileItemNodes.item(j); - if (profileItemNode instanceof Element) { - SigningProfileItem profileItem = new SigningProfileItem(); - Element profileItemElement = (Element) profileItemNode; - String profileItemKey = profileItemElement.getAttribute("key"); //$NON-NLS-1$ - profileItem.setKeyLocation(profileItemKey); - String profileItemIdentifier = profileItemElement.getAttribute("identifier"); //$NON-NLS-1$ - profileItem.setIdentifier(profileItemIdentifier); - String ca = profileItemElement.getAttribute(SigningProfileUtil.ITEM_ATTR_CA); - profileItem.setCAPath(ca); - String pass = profileItemElement.getAttribute(SigningProfileUtil.ITEM_ATTR_PASS); - try { - pass = CipherUtil.getDecryptedString(pass); - } - catch (Exception e) - { - logger.error("Exception occurred while decrypting signing password", e); - } - profileItem.setPassword(pass.toCharArray()); - String rootCA = profileItemElement.getAttribute(SigningProfileUtil.ITEM_ATTR_ROOTCA); - profileItem.setRootCAPath(rootCA); - String profileItemAuthor = profileItemElement.getAttribute(SigningProfileUtil.ITEM_ATTR_AUTHOR); //$NON-NLS-1$ - if (profileItemAuthor.compareTo("true") == 0) { //$NON-NLS-1$ - profileItem.setAuthor(true); - profile.setAuthorItem(profileItem); - } else { - profileItem.setAuthor(false); - profile.addProfileItem(profileItem); - } - } - } - profileList.add(profile); - } - } + if ( file.exists() ) { + return new FileInputStream( file ); } - } catch (ParserConfigurationException e) { - logger.error( "Can't read profiles", e ); - } catch (SAXException e) { - logger.error( "Can't read profiles", e ); - } catch (IOException e) { - logger.error( "Can't read profiles", e ); + } catch ( final IllegalStateException e) { + logger.error( "Can't access state location", e ); + } catch ( final FileNotFoundException e ) { + logger.error( "Can't open profile", e ); } - return profileList; - - } - - public static String getAuthorCAPath() { - return SigningPathUtil.getAuthorCAPath(); + + return null; } - public static String getDeveloperKeyPath() { - return SigningPathUtil.getDeveloperKeyPath(); + public static IPreferenceStore getPreferenceStore() { + return Activator.getDefault().getPreferenceStore(); } - public static String getDeveloperCAPath() { - return SigningPathUtil.getDeveloperCAPath(); + public static String getActiveProfileName() { + return getPreferenceStore().getString( SignatureConstants.DEFAULT_PROFILE_KEY ); } - public static SigningProfile getDefaultProfile(List<SigningProfile> profileList) { - IPreferenceStore preferenceStore = Activator.getDefault().getPreferenceStore(); - - String defaultProfile = preferenceStore.getString(SigningPreferencePage.defaultProfileKey); - - if(defaultProfile == null) { - return null; - } - for(SigningProfile profile: profileList) { - if(defaultProfile.equals(profile.getProfileName())) { - return profile; - } + public static void setActiveProfileName(String profileName) { + if ( profileName == null ) { + profileName = StringUtil.EMPTY_STRING; } - return null; + + getPreferenceStore().setValue( SignatureConstants.DEFAULT_PROFILE_KEY, profileName ); } - /** - * Getter for element by profile name - * @param doc Document - * @param profileName profile name - * @return profile Element - */ - protected static Element getProfileElement(Document doc, String profileName) { - Assert.notNull( doc ); - Assert.notNull( profileName ); - - NodeList profileNodeList = doc.getElementsByTagName( ELEMENT_PROFILE ); - for ( int i = 0; i < profileNodeList.getLength(); i++ ) { - Node profileNode = profileNodeList.item( i ); - boolean matched = XMLUtil.isElementByAttributeWithValue( profileNode, PROFILE_ATTR_NAME, profileName ); - if ( matched ) { - return (Element) profileNode; - } - } - - return null; + public static IPath getProfilesPath() { + return Activator.getDefault().getStateLocation().append( PROFILES_FILE ); } - public static InputStream updateProfiles( InputStream in, final String profileName, final List<SigningProfileItem> items ) - throws ParserConfigurationException, SAXException, IOException, TransformerException { - Assert.notNull( in ); - Assert.notNull( profileName ); - Assert.notNull( items ); - - // read current model - Document doc = XMLUtil.create( in ); - - // find profile - Element profileElement = getProfileElement( doc, profileName ); - if ( profileElement == null ) { - // not found profile element. cannot update profile - return null; - } + public static void writeProfilesToFile(SigningProfileContainer container) { + IPath profilesPath = getProfilesPath(); - // remove old profile items - XMLUtil.removeChildElements( profileElement ); - - // add new profile items - for ( SigningProfileItem item : items ) { - Element itemElement = createSigningProfileItem( doc, item, item.isAuthor() ? "true" : "false" ); - profileElement.appendChild( itemElement ); - } - - // get stream - // TODO: will improve to effective solution. - ByteArrayOutputStream outputStream = null; + FileOutputStream outputStream = null; try { - outputStream = XMLUtil.createOutputStreamFromDocument( doc ); + outputStream = new FileOutputStream( profilesPath.toFile() ); + + container.writeProfileXML( outputStream ); + } catch (FileNotFoundException e) { + logger.error( "Can't write a profile", e ); } finally { IOUtil.tryClose( outputStream ); } - - return new ByteArrayInputStream( outputStream.toByteArray() ); + } + + public static IPath getCertStorePath() { + // <SDK_PATH>/tizen-sdk-data/keystore/ + return new Path( InstallPathConfig.getUserDataPath() ).append( "keystore" ); + } + + public static IPath getAuthorCertStorePath() { + // <SDK_PATH>/tizen-sdk-data/keystore/author/ + return getCertStorePath().append( SignatureConstants.AUTHOR ); } } diff --git a/org.tizen.common.sign/src/org/tizen/common/sign/util/XMLUtil.java b/org.tizen.common.sign/src/org/tizen/common/sign/util/XMLUtil.java index b32b530ef..3ffde230a 100644 --- a/org.tizen.common.sign/src/org/tizen/common/sign/util/XMLUtil.java +++ b/org.tizen.common.sign/src/org/tizen/common/sign/util/XMLUtil.java @@ -43,6 +43,7 @@ import javax.xml.transform.stream.StreamResult; import org.tizen.common.util.Assert; import org.tizen.common.util.FileUtil; +import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -225,4 +226,10 @@ public class XMLUtil } return list; } + + public static void setElementAttribute(Document doc, String attribute, String value, Element parent) { + Attr attr = doc.createAttribute( attribute ); + attr.setNodeValue( value ); + parent.setAttributeNode( attr ); + } } diff --git a/org.tizen.common/src/org/tizen/common/rds/ui/preference/RdsPreferencePage.java b/org.tizen.common/src/org/tizen/common/rds/ui/preference/RdsPreferencePage.java index 9ec84d733..7c1d7a633 100644 --- a/org.tizen.common/src/org/tizen/common/rds/ui/preference/RdsPreferencePage.java +++ b/org.tizen.common/src/org/tizen/common/rds/ui/preference/RdsPreferencePage.java @@ -41,7 +41,11 @@ import org.eclipse.ui.IWorkbenchPreferencePage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.tizen.common.CommonPlugin; +import org.tizen.common.ITizenProject; +import org.tizen.common.TizenProjectType; import org.tizen.common.ui.page.preference.Messages; +import org.tizen.common.util.ProjectUtil; +import org.tizen.common.util.StringUtil; /** @@ -196,15 +200,34 @@ public class RdsPreferencePage extends PropertyAndPreferencePage implements IWor String projectSpecificOption = ""; String rdsOption = OPTION_DISABLE; - // TODO: ad-hoc code. If the project referencing other projects, RDS is disabled. + // TODO: ad-hoc code. If the project is multi-app, RDS is disabled. if ( project != null ) { try { - IProject[] refPrjs = project.getReferencedProjects(); - if (refPrjs.length != 0 ) { + ITizenProject tizenProject = ProjectUtil.getTizenProject(project); + if ( tizenProject == null ) { return false; } + TizenProjectType projectType = tizenProject.getTizenProjectType(); + if ( projectType != null && projectType.isRootProject() == true ) { + IProject[] refPrjs = project.getReferencedProjects(); + for ( IProject refPrj : refPrjs ) { + tizenProject = ProjectUtil.getTizenProject(refPrj); + if ( tizenProject == null ) { + continue; + } + projectType = tizenProject.getTizenProjectType(); + if ( projectType == null || projectType.isReferencedProject() == false ) { + continue; + } + + if ( projectType.isReferencedProject() ) { + return false; + } + } + } } catch (CoreException e) { logger.error("Failed to read the referenced project list.", e); + return false; } } diff --git a/org.tizen.common/src/org/tizen/common/util/DefferedTaskManager.java b/org.tizen.common/src/org/tizen/common/util/DefferedTaskManager.java index 608f0d406..594af641e 100755 --- a/org.tizen.common/src/org/tizen/common/util/DefferedTaskManager.java +++ b/org.tizen.common/src/org/tizen/common/util/DefferedTaskManager.java @@ -165,15 +165,15 @@ DefferedTaskManager public void run()
{
task.run();
- logger.info( "{} was run", task );
+ logger.debug( "{} was run", task );
}
}, delay );
- logger.info( "{} will be run after {}", task, delay );
+ logger.debug( "{} will be run after {}", task, delay );
}
else
{
task.run();
- logger.info( "{} was run", task );
+ logger.debug( "{} was run", task );
}
}
@@ -199,7 +199,7 @@ DefferedTaskManager {
timer.cancel();
timer = null;
- logger.info( "{} canceled", task );
+ logger.debug( "{} canceled", task );
}
}
diff --git a/org.tizen.common/src/org/tizen/common/util/SWTUtil.java b/org.tizen.common/src/org/tizen/common/util/SWTUtil.java index 1e2f65c7e..727450fe0 100755 --- a/org.tizen.common/src/org/tizen/common/util/SWTUtil.java +++ b/org.tizen.common/src/org/tizen/common/util/SWTUtil.java @@ -55,8 +55,6 @@ import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; @@ -140,6 +138,25 @@ public class SWTUtil { } /** + * <p> + * Return {@link Shell} in context + * </p> + * @return {@link Shell} + * + * @see #getDisplay() + */ + public static Shell getShell() + { + Shell shell = getActiveShell(); + if ( null == shell && null != getDisplay() ) + { + shell = getDisplay().getShells()[0]; + } + + return shell; + } + + /** * execute {@link Cabinet#run()} and reeturn the result * * @param runnable object to execute diff --git a/package/changelog b/package/changelog index 990ed2ba2..ca12ef58e 100644 --- a/package/changelog +++ b/package/changelog @@ -1,3 +1,21 @@ +* 2.1.71 +- Release the closed socket channel. +== bonyong.lee <bonyong.lee@samsung.com> 2013-06-24 +* 2.1.70 +- Improved checking a multi-app in isRdsMode() +== gune.kim <gune.kim@samsung.com> 2013-06-24 +* 2.1.69 +- support previous version profiles +== jihoon80.song <jihoon80.song@samsung.com> 2013-06-23 23:10 +* 2.1.68 +- renewal secure profile models +== jihoon80.song <jihoon80.song@samsung.com> 2013-06-23 21:33 +* 2.1.67 +- Added SWTUtil#getShell() +== kh5325.kim <kh5325.kim@samsung.com> 2013-06-22 +* 2.1.66 +- fix a bug where transfer dialog of connection explorer show wrong file size when dropping (pushing) files +== kh5325.kim <kh5325.kim@samsung.com> 2013-06-22 * 2.1.65 - Avoid to throw IndexOutofBoundException when parsing ansi string == kh5325.kim <kh5325.kim@samsung.com> 2013-06-20 diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest index ba6fc5e37..9f31e999e 100644 --- a/package/pkginfo.manifest +++ b/package/pkginfo.manifest @@ -1,4 +1,4 @@ -Version:2.1.65 +Version:2.1.71 Source:common-eplugin Maintainer:kangho kim <kh5325.kim@samsung.com>, yoonki park <yoonki.park@samsung.com>, hyunsik non <hyunsik.noh@samsung.com>, taeyoung son <taeyoung2.son@samsung.com>, gune Kim <gune.kim@samsung.com>, ho namkoong <ho.namkoong@samsung.com>, hyeongseok heo <hyeong-seok.heo@samsung.com>, gyeongseok seo <gyeongseok.seo@samsung.com>, jihoon song <jihoon80.song@samsung.com>, changhyun lee <changhyun1.lee@samsung.com>, bonyong lee <bonyong.lee@samsung.com>, shingil kang <shingil.kang@samsung.com> |