MetaData.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
eclipseme.core.model.impl |
![]() |
![]() |
EclipseME |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
********************************************************************
*
* Filename : MetaData.java
* Package : eclipseme.core.model.impl
* System : eclipseme.core
* Author : Craig Setera
* Description : Class for managing metadata for J2ME projects
*
* Copyright (c) 2003-2005 Craig Setera
* All Rights Reserved.
* Licensed under the Eclipse Public License - v 1.0
* For more information see http://www.eclipse.org/legal/epl-v10.html
*
* Refactored, and signature additions by Kevin Hunter, 2004
*
* CVS
* $$Source: /cvsroot/eclipseme/eclipseme.core/src/eclipseme/core/model/impl/MetaData.java,v $$
* $$Author: setera $$
* $$Date: 2006/11/12 01:11:03 $$
* $$Revision: 1.15 $$
*
********************************************************************
*/
package eclipseme.core.model.impl;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import eclipseme.core.EclipseMECoreErrors;
import eclipseme.core.internal.EclipseMECorePlugin;
import eclipseme.core.internal.signing.Base64EncDec;
import eclipseme.core.internal.utils.XMLUtils;
import eclipseme.core.model.ISignatureProperties;
import eclipseme.core.model.Version;
import eclipseme.core.model.device.DeviceRegistry;
import eclipseme.core.model.device.IDevice;
import eclipseme.core.persistence.PersistenceException;
import eclipseme.core.signing.RC4Engine;
import eclipseme.core.signing.SignatureProperties;
/**
* This class holds the metadata for the midlet suite
* project. This information is persisted to a file called
* ".eclipseme" in the project's root directory.
* <p>
* <b>Note:</b> This class/interface is part of an interim API that is still under development and expected to
* change before reaching stability. It is being made available at this early stage to solicit feedback
* from pioneering adopters on the understanding that any code that uses this API will almost
* certainly be broken as the API evolves.
* </p>
*/
public class MetaData
{
public static final String METADATA_FILE = ".eclipseme";
private static final String ELEM_ROOT_NAME = "eclipsemeMetadata";
private static final String ATTR_JAD_FILE = "jad";
private static final String ELEM_SIGNING = "signing";
private static final String ATTR_SIGN_PROJECT = "signProject";
private static final String ELEM_KEYSTORE = "keystore";
private static final String ELEM_ALIAS = "alias";
private static final String ELEM_PROVIDER = "provider";
private static final String ELEM_KEYSTORETYPE = "keystoreType";
private static final String ELEM_PASSWORDS = "passwords";
private static final String ATTR_STOREPASSWORDS = "storePasswords";
private static final String ELEM_PWD_KEYSTORE = "keystore";
private static final String ELEM_PWD_KEY = "key";
// Device related constants
private static final String ELEM_DEVICE = "device";
private static final String ATTR_DEVICEGROUP = "group";
private static final String ATTR_DEVICENAME = "name";
private static final String cryptoPass = "EclipseME";
private static final String KEYRING_URL_BASE = "http://projects.eclipseme/";
private static final String KEYRING_REALM = "projects";
private static final String KEYRING_SCHEME = "EclipseME";
private static final String KEYRING_KEYSTOREPASS_KEY = "KeystorePass";
private static final String KEYRING_KEYPASS_KEY = "KeyPass";
private IProject project;
private Version version;
private IDevice device;
private String jadFile;
private SignatureProperties signatureProps;
/**
* Construct a new metadata object for the
* midlet suite project.
*
* @param suite
*/
public MetaData(MidletSuiteProject suite) {
this(suite.getJavaProject().getProject());
}
/**
* Construct a new metadata object for the
* midlet suite project.
*
* @param suite
*/
public MetaData(IProject project) {
this.project = project;
try {
loadMetaData();
} catch (CoreException e) {
// Failure to load the metadata, log and initialize to defaults
EclipseMECorePlugin.log(IStatus.ERROR, "loadMetaData() failed", e);
initializeToDefaults();
}
}
/**
* Return the IFile instance in which the metadata is to be stored
* or <code>null</code> if the file is not yet available.
*
* @return
*/
private IFile getStoreFile()
{
IFile storeFile = null;
if (project != null) {
storeFile = project.getFile(METADATA_FILE);
}
return storeFile;
}
/**
* Initialize the metadata to default values
*/
private void initializeToDefaults() {
signatureProps = new SignatureProperties();
}
private void loadMetaData() throws CoreException
{
boolean bRewrite = false;
loadMetaDataFromFile();
if (signatureProps == null)
{
signatureProps = new SignatureProperties();
signatureProps.clear();
bRewrite = true;
}
if (bRewrite)
{
// NOTE: Commented out for now. The point at which this is likely to
// happen (during startup), the workspace is locked against updates
// and the save will fail. (Actually the workspace refresh will fail)
// saveMetaData();
}
}
private void loadMetaDataFromFile() throws CoreException
{
IFile storeFile = getStoreFile();
if ((storeFile != null) && (storeFile.exists())) {
try
{
File localFile = storeFile.getLocation().toFile();
Document document = XMLUtils.readDocument(localFile);
if (document == null)
{
return;
}
Element rootElement = document.getDocumentElement();
if (!rootElement.getNodeName().equals(ELEM_ROOT_NAME))
{
return;
}
version = XMLUtils.getVersion(document);
jadFile = rootElement.getAttribute(ATTR_JAD_FILE);
loadDevice(rootElement);
loadSignatureProperties(rootElement);
}
catch(ParserConfigurationException pce)
{
EclipseMECorePlugin.throwCoreException(
IStatus.WARNING,
99999,
pce);
}
catch(SAXException se)
{
EclipseMECorePlugin.throwCoreException(
IStatus.WARNING,
99999,
se);
}
catch(IOException ioe)
{
EclipseMECorePlugin.throwCoreException(
IStatus.WARNING,
99999,
ioe);
} catch (PersistenceException e) {
EclipseMECorePlugin.throwCoreException(
IStatus.WARNING,
99999,
e);
}
} else {
initializeToDefaults();
}
}
private void loadDevice(Element rootElement)
throws PersistenceException
{
Element deviceElement = XMLUtils.getFirstElementWithTagName(rootElement, ELEM_DEVICE);
if (deviceElement != null) {
String deviceGroup = deviceElement.getAttribute(ATTR_DEVICEGROUP);
String deviceName = deviceElement.getAttribute(ATTR_DEVICENAME);
device = DeviceRegistry.singleton.getDevice(deviceGroup, deviceName);
}
}
private void loadSignatureProperties(Element rootElement) throws CoreException
{
SignatureProperties sp = new SignatureProperties();
Element signRoot = XMLUtils.getFirstElementWithTagName(rootElement, ELEM_SIGNING);
if (signRoot == null)
{
return;
}
String attr = signRoot.getAttribute(ATTR_SIGN_PROJECT);
if (attr == null)
{
return;
}
if (!Boolean.valueOf(attr).booleanValue())
{
sp.setSignProject(false);
signatureProps = sp;
return;
}
sp.setSignProject(true);
Element e;
e = XMLUtils.getFirstElementWithTagName(signRoot, ELEM_KEYSTORE);
if (e == null)
{
return;
}
sp.setKeyStoreDisplayPath(XMLUtils.getElementText(e));
e = XMLUtils.getFirstElementWithTagName(signRoot, ELEM_ALIAS);
if (e == null)
{
return;
}
sp.setKeyAlias(XMLUtils.getElementText(e));
e = XMLUtils.getFirstElementWithTagName(signRoot, ELEM_PROVIDER);
if (e != null)
{
sp.setKeyStoreProvider(XMLUtils.getElementText(e));
}
e = XMLUtils.getFirstElementWithTagName(signRoot, ELEM_KEYSTORETYPE);
if (e != null)
{
sp.setKeyStoreType(XMLUtils.getElementText(e));
}
e = XMLUtils.getFirstElementWithTagName(signRoot, ELEM_PASSWORDS);
if (e != null)
{
attr = e.getAttribute(ATTR_STOREPASSWORDS);
int nMethod = ISignatureProperties.PASSMETHOD_PROMPT;
if (attr != null)
{
try
{
nMethod = Integer.valueOf(attr).intValue();
}
catch(Exception ex)
{
}
}
Map keyMap;
switch(nMethod)
{
case ISignatureProperties.PASSMETHOD_IN_KEYRING:
sp.setPasswordStorageMethod(nMethod);
keyMap = Platform.getAuthorizationInfo(getKeyringURL(), KEYRING_REALM, KEYRING_SCHEME);
if (keyMap != null)
{
sp.setKeyStorePassword((String)keyMap.get(KEYRING_KEYSTOREPASS_KEY));
sp.setKeyPassword((String)keyMap.get(KEYRING_KEYPASS_KEY));
}
break;
case ISignatureProperties.PASSMETHOD_IN_PROJECT:
sp.setPasswordStorageMethod(nMethod);
sp.setKeyStorePassword(decodePassword(e, ELEM_PWD_KEYSTORE));
sp.setKeyPassword(decodePassword(e, ELEM_PWD_KEY));
break;
case ISignatureProperties.PASSMETHOD_PROMPT:
default:
sp.setPasswordStorageMethod(ISignatureProperties.PASSMETHOD_PROMPT);
sp.setKeyStorePassword(null);
sp.setKeyPassword(null);
break;
}
}
signatureProps = sp;
}
private String encodePassword(String password)
{
if (password == null)
{
return("");
}
try
{
byte[] passwordBytes = password.getBytes("UTF8");
byte[] cryptBytes = new byte[passwordBytes.length];
RC4Engine crypter = new RC4Engine();
crypter.setKey(cryptoPass.getBytes("UTF8"));
crypter.processBytes(passwordBytes, 0, passwordBytes.length, cryptBytes, 0);
return(Base64EncDec.encode(cryptBytes));
}
catch(UnsupportedEncodingException e)
{
}
return("");
}
private String decodePassword(Element base, String subElementName)
{
Element subElement = XMLUtils.getFirstElementWithTagName(base, subElementName);
if (subElement == null)
{
return(null);
}
String encoded = XMLUtils.getElementText(subElement);
byte[] cryptBytes = Base64EncDec.decode(encoded);
if (cryptBytes == null)
{
return(null);
}
try
{
byte[] passwordBytes = new byte[cryptBytes.length];
RC4Engine crypter = new RC4Engine();
crypter.setKey(cryptoPass.getBytes("UTF8"));
crypter.processBytes(cryptBytes, 0, cryptBytes.length, passwordBytes, 0);
return(new String(passwordBytes, "UTF8"));
}
catch(UnsupportedEncodingException e)
{
}
return(null);
}
/**
* Attempt to save the metadata. This has the potential to fail.
* @throws CoreException
*/
public void saveMetaData()
throws CoreException
{
IFile storeFile = getStoreFile();
if (storeFile == null) {
EclipseMECorePlugin.log(IStatus.WARNING, "saveMetaData failed due to null store file");
} else {
if (storeFile.exists() && storeFile.isReadOnly()) {
// Attempt to clear the read-only flag via the IResource
// interface. This should invoke the team provider and
// do necessary checkouts.
ResourceAttributes attributes = storeFile.getResourceAttributes();
attributes.setReadOnly(false);
storeFile.setResourceAttributes(attributes);
}
saveMetaDataToFile(storeFile);
}
}
/**
* Save the metadata to the storage file. This file is expected to
* be non-null.
*
* @param storeFile
* @throws CoreException
*/
public void saveMetaDataToFile(IFile storeFile)
throws CoreException
{
try {
String pluginVersion = EclipseMECorePlugin.getPluginVersion();
Version newVersion = new Version(pluginVersion);
Element rootElement = XMLUtils.createRootElement(ELEM_ROOT_NAME, newVersion);
if (jadFile != null) {
rootElement.setAttribute(ATTR_JAD_FILE, jadFile);
}
if (device != null) {
Element deviceElement = XMLUtils.createChild(rootElement, ELEM_DEVICE);
deviceElement.setAttribute(ATTR_DEVICEGROUP, device.getGroupName());
deviceElement.setAttribute(ATTR_DEVICENAME, device.getName());
}
Element signRoot = XMLUtils.createChild(rootElement, ELEM_SIGNING);
boolean bSign = signatureProps.getSignProject();
signRoot.setAttribute(ATTR_SIGN_PROJECT, Boolean.toString(bSign));
if (bSign)
{
XMLUtils.createTextElement(signRoot, ELEM_KEYSTORE, signatureProps.getKeyStoreDisplayPath());
XMLUtils.createTextElement(signRoot, ELEM_ALIAS, signatureProps.getKeyAlias());
XMLUtils.createTextElement(signRoot, ELEM_PROVIDER, signatureProps.getKeyStoreProvider());
XMLUtils.createTextElement(signRoot, ELEM_KEYSTORETYPE, signatureProps.getKeyStoreType());
Element passRoot = XMLUtils.createChild(signRoot, ELEM_PASSWORDS);
passRoot.setAttribute(ATTR_STOREPASSWORDS, Integer.toString(signatureProps.getPasswordStorageMethod()));
Map keyMap;
Platform.flushAuthorizationInfo(getKeyringURL(), KEYRING_REALM, KEYRING_SCHEME);
switch(signatureProps.getPasswordStorageMethod())
{
case ISignatureProperties.PASSMETHOD_IN_PROJECT:
XMLUtils.createTextElement(passRoot, ELEM_PWD_KEYSTORE, encodePassword(signatureProps.getKeyStorePassword()));
XMLUtils.createTextElement(passRoot, ELEM_PWD_KEY, encodePassword(signatureProps.getKeyPassword()));
break;
case ISignatureProperties.PASSMETHOD_IN_KEYRING:
keyMap = new HashMap();
keyMap.put(KEYRING_KEYSTOREPASS_KEY, signatureProps.getKeyStorePassword());
keyMap.put(KEYRING_KEYPASS_KEY, signatureProps.getKeyPassword());
Platform.addAuthorizationInfo(getKeyringURL(), KEYRING_REALM, KEYRING_SCHEME, keyMap);
break;
case ISignatureProperties.PASSMETHOD_PROMPT:
default:
break;
}
}
File localFile = storeFile.getLocation().toFile();
XMLUtils.writeDocument(localFile, rootElement.getOwnerDocument());
version = newVersion;
getStoreIFile().refreshLocal(1, new NullProgressMonitor());
}
catch(ParserConfigurationException pce)
{
EclipseMECorePlugin.throwCoreException(
IStatus.WARNING,
99999,
pce);
}
catch(TransformerException te)
{
EclipseMECorePlugin.throwCoreException(
IStatus.WARNING,
99999,
te);
}
catch(IOException ioe)
{
EclipseMECorePlugin.throwCoreException(
IStatus.WARNING,
99999,
ioe);
}
}
/**
* Return the device stored in the project metadata.
* @return
*/
public IDevice getDevice() {
return device;
}
/**
* Return the project-relative path to the project's jad file as
* specified in the project's metadata file. If the attributes
* has not been set, this method will return an empty string.
*
* @return
*/
public String getJadFile()
{
return jadFile;
}
/**
* Set the device stored in the project metadata.
*
* @param device
*/
public void setDevice(IDevice device) {
this.device = device;
}
/**
* Set the project-relative path to the project's jad file.
*
* @param jadFile
*/
public void setJadFile(String jadFile)
{
this.jadFile = jadFile;
}
public ISignatureProperties getSignatureProperties() throws CoreException
{
return signatureProps;
}
/**
* @return Returns the version.
*/
public Version getVersion() {
return version;
}
public void setSignatureProperties(ISignatureProperties p)
{
if (signatureProps == null)
{
signatureProps = new SignatureProperties();
}
signatureProps.copy(p);
}
/**
* Get the IFile instance in which the metadata is to be stored.
*
* @return
*/
private IFile getStoreIFile() {
return project.getFile(METADATA_FILE);
}
private URL getKeyringURL() throws CoreException
{
StringBuffer buf = new StringBuffer();
buf.append(KEYRING_URL_BASE);
String projectName = project.getName();
int nLength = projectName.length();
for (int i = 0; i < nLength; i++)
{
char c = projectName.charAt(i);
if (Character.isLetterOrDigit(c) || c == '.')
{
buf.append(c);
}
else
{
buf.append('%');
String hexString = Integer.toHexString((int)c);
if ((hexString.length() & 0x01) != 0)
{
buf.append('0');
}
buf.append(hexString);
}
}
URL retval = null;
try
{
retval = new URL(buf.toString());
}
catch(Exception ex)
{
EclipseMECoreErrors.throwCoreExceptionError(EclipseMECoreErrors.SIGNING_INTERNAL_UNABLE_TO_BUILD_KEYRING_URL, ex);
}
return(retval);
}
}
/*
********************************************************************
* CVS History:
* $$Log: MetaData.java,v $
* $Revision 1.15 2006/11/12 01:11:03 setera
* $Merging the preprocessor functionality back to the mainline
* $
* $Revision 1.14.4.2 2006/10/09 13:48:24 setera
* $Transitioning to secondary project for preprocessed output
* $
* $Revision 1.14.4.1 2006/09/14 00:49:10 setera
* $More preprocessing work via file system
* $
* $Revision 1.14 2006/05/29 00:43:02 setera
* $Use the resource API to set files read/write before saving (Bugs 1454656 & 1471342)
* $
* $Revision 1.13 2006/02/11 21:26:56 setera
* $Massive rework of emulator/device handling
* $
* $Revision 1.12 2005/12/18 19:36:57 setera
* $- Improve midlet refactoring support for JAD files including midlet moves and deletes
* $- Improve JAD file refactoring, allowing the JAD file to be moved and renamed
* $- Allow JAD file location during midlet suite creation (RFE 1044272)
* $
* $Revision 1.11 2005/10/29 15:39:29 setera
* $Refactor packaging and signing functionality into their own packages
* $Warn user while trying to package a project with an invalid platform definition (Bug 1304273)
* $
* $Revision 1.10 2005/07/07 02:37:17 setera
* $Final updates for 1.0.0 release
* $
* $Revision 1.9 2005/02/19 23:39:44 setera
* $Migration support for new identifier requirement
* $
* $Revision 1.8 2005/02/12 23:56:06 setera
* $First pass at platform component identifier support
* $
* $Revision 1.7 2004/12/17 01:33:29 setera
* $Documentation updates for the 0.7.0
* $
* $Revision 1.6 2004/12/16 00:56:57 setera
* $Fix some midlet suite metadata regression problems
* $
* $Revision 1.5 2004/12/15 01:24:28 setera
* $Fix some potential concurrency issues
* $
* $Revision 1.4 2004/12/12 20:21:10 kdhunter
* $Support for storing passwords in keyring
* $
* $Revision 1.3 2004/12/09 01:21:00 kdhunter
* $Mods to support two different buttons for "external"
* $or "internal" keystore files
* $
* $Revision 1.2 2004/12/07 01:10:19 kdhunter
* $Changes to allow project-relative or absolute
* $keystore paths
* $
* $Revision 1.1 2004/11/27 04:31:46 kdhunter
* $Refactored MetaData out of MidletSuiteProject
* $Additions for signing support
* $$
*
********************************************************************
*/
The table below shows all metrics for MetaData.java.




