themeinstaller/source/src/com/nokia/tools/themeinstaller/installationmanager/ManifestFactory.java
branchRCL_3
changeset 32 fe49e33862e2
parent 31 b685c59de105
child 33 04b7640f6fb5
--- a/themeinstaller/source/src/com/nokia/tools/themeinstaller/installationmanager/ManifestFactory.java	Thu Aug 19 09:43:47 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,593 +0,0 @@
-/*
- * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). 
- * All rights reserved.
- * This component and the accompanying materials are made available
- * under the terms of "Eclipse Public License v1.0"
- * which accompanies this distribution, and is available
- * at the URL "http://www.eclipse.org/legal/epl-v10.html".
- *
- * Initial Contributors:
- * Nokia Corporation - initial contribution.
- *
- * Contributors:
- *
- * Description:  Uses XML parser to read the manifest and created objects that
- *                represent the manifest.
- *
- */
-
-package com.nokia.tools.themeinstaller.installationmanager;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Vector;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import com.nokia.tools.themeinstaller.localisation.DTDReader;
-import com.nokia.tools.themeinstaller.localisation.Localisation;
-import com.nokia.tools.themeinstaller.localisation.LocalisationStore;
-import com.nokia.tools.themeinstaller.odtconverter.ConverterProperties;
-import com.nokia.tools.themeinstaller.odtconverter.IParseOperationListener;
-import com.nokia.tools.themeinstaller.odtconverter.MimeTypeResolver;
-import com.nokia.tools.themeinstaller.odtconverter.ThemeStatusResolver;
-import com.nokia.tools.themeinstaller.xmlparser.XMLParser;
-
-/**
- * Uses XML parser to read the manifest and created objects that represent the
- * manifest.
- */
-public class ManifestFactory implements IParseOperationListener {
-
-	// CONSTANTS
-	// Manifest root node names
-	private static final String MULTI_THEME = "datfiles";
-
-	// Manifest element names
-	private static final String APP_UID_ELEMENT = "AppUid";
-	private static final String PROVIDER_UID_ELEMENT = "Provideruid";
-	private static final String THEME_UID_ELEMENT = "ThemeUid";
-	private static final String THEME_STATUS_ELEMENT = "ThemeStatus";
-	private static final String THEME_FULL_NAME_ELEMENT = "ThemeFullName";
-	private static final String THEME_SHORT_NAME_ELEMENT = "ThemeShortName";
-	private static final String THEME_VERSION_ELEMENT = "ThemeVersion";
-	private static final String FILE_XML_ELEMENT = "FileXML";
-	private static final String FILE_CSS_ELEMENT = "FileCSS";
-	private static final String FILE_DTD_ELEMENT = "FileDTD";
-	private static final String FILE_DAT_ELEMENT = "FileDAT";
-	private static final String FILE_RESOURCE_ELEMENT = "FileResource";
-	private static final String CACHE_VALUE_MEMORY = "CacheMemory";
-	private static final String LOCKING_ELEMENT = "Locking";
-	private static final String LOCKED_VALUE = "Locked";
-	private static final String CACHE_TYPE_ELEMENT = "CacheType";
-	private static final String CACHE_VALUE_NONE = "CacheNone";
-	private static final String CACHE_VALUE_FILE = "CacheFile";
-
-	// Language element names
-	private static final String LANGUAGE_SPECIFIC_ELEMENT = "LanguageSpecific";
-	private static final int LANGUAGE_INDEPENDENT = 0;
-	private static final int LANG_NOT_SET = -1;
-
-	// Integer conversion radix
-	private static final int RADIX = 16;
-
-	// Screen size
-	private static final int SCREEN_SIZE_X = 0;
-	private static final int SCREEN_SIZE_Y = 0;
-
-	// Resource file cache type
-	public static int CACHE_TYPE_CACHE_NONE = 0;
-	public static int CACHE_TYPE_CACHE_FILE = 1;
-	public static int CACHE_TYPE_CACHE_MEMORY = 2;
-
-	// Locking policy flag-definition from native, bit-masked.
-	public static final int E_XN_UNLOCKED = 0x0000; // 0b0000000000000000,
-	public static final int E_XN_LOCKED = 0x0001; // 0b0000000000000001,
-
-	public static final String CURRENT_DIR = ".";
-
-	// Property keys
-	private static final String THEME_PROVIDER_KEY = "theme_provider_name";
-	private static final String NAME_SPACE_KEY = "theme_name_space";
-
-	// Lock for monitoring parse operation completions
-	private Lock iLock;
-
-	// Mime type resolver
-	private MimeTypeResolver iMimeTypeResolver;
-
-	// Converter properties
-	private ConverterProperties iProperties;
-
-	// Localisation settings
-	private File iLocSettings;
-
-	/**
-	 * Constructor.
-	 * 
-	 * @param aLocSettings
-	 *            Localisation settings
-	 * @throws IOException
-	 *             if converter properties can not be read
-	 */
-	public ManifestFactory(File aLocSettings) throws IOException {
-		iLock = new Lock();
-		iMimeTypeResolver = new MimeTypeResolver();
-		iProperties = ConverterProperties.getInstance();
-		iLocSettings = aLocSettings;
-	}
-
-	/**
-	 * Parse a manifest and create the manifest object.
-	 * 
-	 * @param aFile
-	 *            Manifest file
-	 * @return Manifest instance
-	 * @throws IOException
-	 *             if the manifest can not be read
-	 */
-	public IThemeManifest createManifest(File aFile) throws IOException {
-		// Read the manifest to the DOM document
-		Document document = readManifest(aFile);
-		IThemeManifest manifest = new ThemeManifest();
-
-		// Set data directory that contains the data files of the theme
-		if (aFile.getParent() == null) {
-			manifest.setDataDir(CURRENT_DIR + File.separatorChar);
-		} else {
-			manifest.setDataDir(aFile.getParent() + File.separatorChar);
-		}
-
-		// Parse manifest contents
-		String rootNodeName = document.getFirstChild().getNodeName();
-		if (rootNodeName == MULTI_THEME) {
-			// Multi theme manifest
-			parseMultiThemeManifest(document, manifest);
-		} else {
-			// Single theme manifest
-			parseManifest(document, manifest);
-			parseLanguageSpecificData(document, manifest);
-			parseResources(document, manifest, LANGUAGE_INDEPENDENT);
-		}
-
-		return manifest;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @seecom.nokia.tools.themeinstaller.odtconverter.IParseOperationListener#
-	 * parseOperationCompleted(int, java.lang.String)
-	 */
-	public void parseOperationCompleted(int aErr, String aReason) {
-		iLock.unLock();
-		if (aErr != 0) {
-			throw new IllegalArgumentException(
-					"Theme manifest parsing failed: " + aErr + ", " + aReason);
-		}
-	}
-
-	/**
-	 * Parse the manifest file.
-	 * 
-	 * @param aManifest
-	 *            Manifest file
-	 * @return DOM Document of the manifest
-	 */
-	private Document readManifest(File aManifest) {
-		// Parse the manifest
-		XMLParser parser = new XMLParser(aManifest.getPath());
-		parser.addListener(this);
-
-		try {
-			parser.parse();
-		} catch (Exception e) {
-			throw new IllegalArgumentException(
-					"Theme manifest parsing failed: " + e.getMessage());
-		}
-
-		// Wait for the operation completion
-		iLock.lock();
-
-		// Return the document that was formed
-		return parser.getDOMDocument();
-	}
-
-	/**
-	 * Parses a multi theme manifest from DOM to the manifest instance.
-	 * 
-	 * @param aDocument
-	 *            DOM Document containing the manifest data (source)
-	 * @param aManifest
-	 *            Theme manifest (destination)
-	 */
-	private void parseMultiThemeManifest(Document aDocument,
-			IThemeManifest aManifest) {
-		// Add DAT file names
-		NodeList nodes = aDocument.getElementsByTagName(FILE_DAT_ELEMENT);
-		Node node = null;
-		for (int i = 0; i < nodes.getLength(); i++) {
-			node = nodes.item(i);
-			aManifest.addManifestFile(aManifest.getDataDir()
-					+ node.getTextContent());
-		}
-	}
-
-	/**
-	 * Parses a manifest from DOM to the manifest instance.
-	 * 
-	 * @param aDocument
-	 *            DOM Document containing the manifest data (source)
-	 * @param aManifest
-	 *            Theme manifest (destination)
-	 */
-	private void parseManifest(Document aDocument, IThemeManifest aManifest) {
-		// Set application uid
-		NodeList nodes = aDocument.getElementsByTagName(APP_UID_ELEMENT);
-		Node node = checkOneNode(nodes, APP_UID_ELEMENT);
-		if (node != null)
-			aManifest.setApplicationUid(Long.valueOf(node.getTextContent(),
-					RADIX));
-
-		// Set provider uid
-		nodes = aDocument.getElementsByTagName(PROVIDER_UID_ELEMENT);
-		node = checkOneNode(nodes, PROVIDER_UID_ELEMENT);
-		if (node != null)
-			aManifest
-					.setProviderUid(Long.valueOf(node.getTextContent(), RADIX));
-
-		// Set theme uid
-		nodes = aDocument.getElementsByTagName(THEME_UID_ELEMENT);
-		node = checkOneNode(nodes, THEME_UID_ELEMENT);
-		if (node != null)
-			aManifest.setThemeUid(Long.valueOf(node.getTextContent(), RADIX));
-
-		// Set name space
-		aManifest.setNameSpace(iProperties.getProperty(NAME_SPACE_KEY));
-
-		// Set theme provider name
-		aManifest.setProviderName(iProperties.getProperty(THEME_PROVIDER_KEY));
-
-		// Set default theme full name before localization
-		nodes = aDocument.getElementsByTagName(THEME_FULL_NAME_ELEMENT);
-		if (nodes.getLength() > 0) {
-			// Get first theme name that is found (for a default name).
-			// The used name is specified in the language specific data.
-			aManifest.setThemeFullName(nodes.item(0).getTextContent());
-		}
-		// else
-		// {
-		// throw new IllegalArgumentException(
-		// "Syntax error in manifest file: theme full name not found" );
-		// }
-
-		// Set theme short name
-		nodes = aDocument.getElementsByTagName(THEME_SHORT_NAME_ELEMENT);
-		node = checkOneNode(nodes, THEME_SHORT_NAME_ELEMENT);
-		if (node != null)
-			aManifest.setThemeShortName(node.getTextContent());
-
-		// Set theme version
-		nodes = aDocument.getElementsByTagName(THEME_VERSION_ELEMENT);
-		node = checkOneNode(nodes, THEME_VERSION_ELEMENT);
-		if (node != null)
-			aManifest.setThemeVersion(node.getTextContent());
-
-		// Screen size, not used in Xuikon at the moment
-		aManifest.setScreenSizeX(new Integer(SCREEN_SIZE_X));
-		aManifest.setScreenSizeY(new Integer(SCREEN_SIZE_Y));
-
-		// Resolve theme status
-		nodes = aDocument.getElementsByTagName(THEME_STATUS_ELEMENT);
-		int flags = ThemeStatusResolver.E_XN_THEME_STATUS_NONE;
-		for (int i = 0; i < nodes.getLength(); i++) {
-			node = nodes.item(i);
-			flags |= ThemeStatusResolver.getValue(node.getTextContent())
-					.intValue();
-			if (node.getTextContent().equals(
-					ThemeStatusResolver.THEME_STATUS_LICENCEE_RESTORABLE)) {
-				// This theme is restored when licensee default theme is
-				// restored.
-				// When using this flag, the ThemeStatusLicenceeDefault-flag
-				// must be activated.
-				flags |= ThemeStatusResolver.E_XN_THEME_STATUS_LICENCEE_DEFAULT;
-			}
-		}
-		aManifest.setThemeStatus(new Integer(flags));
-
-		// Set XML file name
-		NodeList files = aDocument.getElementsByTagName(FILE_XML_ELEMENT);
-		node = checkOneNode(files, FILE_XML_ELEMENT);
-		if (node != null)
-			aManifest.setXMLFile(node.getTextContent());
-
-		// Set CSS file name
-		files = aDocument.getElementsByTagName(FILE_CSS_ELEMENT);
-		node = checkMaxOneLanguageIndependentNode(files);
-		if (node != null) {
-			aManifest.setCSSFile(node.getTextContent());
-		}
-
-		// Set DTD file name
-		files = aDocument.getElementsByTagName(FILE_DTD_ELEMENT);
-		node = checkMaxOneLanguageIndependentNode(files);
-		if (node != null) {
-			aManifest.setDTDFile(node.getTextContent());
-		}
-	}
-
-	/**
-	 * Parses language specific data in the manifest.
-	 * 
-	 * @param aDocument
-	 *            DOM Document containing the manifest data (source)
-	 * @param aManifest
-	 *            Theme manifest (destination)
-	 * @throws IOException
-	 *             if the manifest can not be parsed
-	 */
-	private void parseLanguageSpecificData(Document aDocument,
-			IThemeManifest aManifest) throws IOException {
-		// Get languages
-		NodeList languages = aDocument
-				.getElementsByTagName(LANGUAGE_SPECIFIC_ELEMENT);
-
-		Node langSpecificNode = null;
-		NamedNodeMap langAttr = null;
-		NodeList langSpecificChildren = null;
-		Node langSpecificChild = null;
-
-		NodeList resources = aDocument
-				.getElementsByTagName(FILE_RESOURCE_ELEMENT);
-		Vector langResources = null;
-
-		// Process all languages
-		for (int i = 0; i < languages.getLength(); i++) {
-			// Language specific data
-			int langId = LANG_NOT_SET;
-			String extDtd = null;
-			String extCss = null;
-			String themeFullName = null;
-
-			// Take a LanguageSpecific node
-			langSpecificNode = languages.item(i);
-
-			// There should be only one language for each LanguageSpecific node
-			langAttr = langSpecificNode.getAttributes();
-			if (langAttr.getLength() == 1) {
-				String langStr = langAttr.item(0).getNodeValue();
-				langId = Integer.valueOf(langStr).intValue();
-			}
-
-			langSpecificChildren = langSpecificNode.getChildNodes();
-
-			// Read language specific elements
-			String nodeName = null;
-
-			for (int j = 0; j < langSpecificChildren.getLength(); j++) {
-				langSpecificChild = langSpecificChildren.item(j);
-				nodeName = langSpecificChild.getNodeName();
-
-				// Language specific DTD file name
-				if (FILE_DTD_ELEMENT.equals(nodeName)) {
-					extDtd = langSpecificChild.getTextContent();
-				}
-				// Language specific CSS
-				else if (FILE_CSS_ELEMENT.equals(nodeName)) {
-					extCss = langSpecificChild.getTextContent();
-				}
-				// Localized theme full name
-				else if (THEME_FULL_NAME_ELEMENT.equals(nodeName)) {
-					themeFullName = langSpecificChild.getTextContent();
-				}
-			}
-
-			// Parse language specific resources
-			langResources = parseResources(aManifest, resources, langId);
-
-			// Verify that mandatory fields language id and DTD file were set
-			if (langId == LANG_NOT_SET || extDtd == null) {
-				throw new IllegalArgumentException(
-						"Syntax error in language specifications of the manifest");
-			}
-
-			// Find the DTD file for reading the localised theme full name
-			File dtd = null;
-			if (iLocSettings != null) {
-				// Use enhanced localisation: Find the DTD file
-				LocalisationStore ls = LocalisationStore
-						.getInstance(iLocSettings);
-				Localisation l = ls.getLocalisation(aManifest
-						.getApplicationUid().longValue(), aManifest
-						.getProviderUid().longValue(), aManifest.getThemeUid()
-						.longValue());
-				dtd = l.findDTD(extDtd);
-			} else {
-				dtd = new File(aManifest.getDataDir() + extDtd);
-			}
-
-			// Resolve localised theme full name, if specified
-			themeFullName = DTDReader.readEntity(dtd, themeFullName);
-
-			// Create new language specific data and add it to the languages
-			// list
-			LanguageSpecificData language = new LanguageSpecificData(
-					new Integer(langId), extDtd, extCss, themeFullName,
-					langResources);
-			aManifest.addLanguage(language);
-		}
-
-		// Unlocalized variant (causes the .o0000 file to be generated)
-		LanguageSpecificData language = new LanguageSpecificData(new Integer(
-				LANGUAGE_INDEPENDENT), null, null, null, null);
-		aManifest.addLanguage(language);
-	}
-
-	/**
-	 * Parses resource data in the manifest.
-	 * 
-	 * @param aDocument
-	 *            DOM Document containing the manifest data (source)
-	 * @param aManifest
-	 *            Theme manifest (destination)
-	 * @param aLanguageId
-	 *            Id of the language of which resources will be parsed. On 0,
-	 *            only language independent resources are parsed.
-	 */
-	private void parseResources(Document aDocument, IThemeManifest aManifest,
-			int aLanguageId) {
-		// Do the parsing operation
-		NodeList resourceList = aDocument
-				.getElementsByTagName(FILE_RESOURCE_ELEMENT);
-		Vector resources = parseResources(aManifest, resourceList, aLanguageId);
-
-		// Add resources to the manifest
-		Enumeration e = resources.elements();
-		while (e.hasMoreElements()) {
-			aManifest.addResource((ThemeResource) e.nextElement());
-		}
-	}
-
-	/**
-	 * Parses resource files defined in the manifest. Resources must be parsed
-	 * after the rest of the manifest is parsed. Theme status is used here for
-	 * determining locking policies.
-	 * 
-	 * @param aManifest
-	 *            Theme manifest
-	 * @param aNodeList
-	 *            Node list to parse
-	 * @param aLanguageId
-	 *            Id of the language of which resources will be parsed. On 0,
-	 *            only language independent resources are parsed.
-	 */
-	private Vector parseResources(IThemeManifest aManifest, NodeList aNodeList,
-			int aLanguageId) {
-		Vector result = new Vector();
-		Node node = null;
-
-		// Browse through all resources in the list
-		int count = aNodeList.getLength();
-		for (int i = 0; i < count; i++) {
-			node = aNodeList.item(i);
-			String filename = node.getTextContent();
-			NamedNodeMap attributes = node.getAttributes();
-
-			int cacheType = CACHE_TYPE_CACHE_NONE;
-			int lockingPolicy = E_XN_UNLOCKED;
-
-			// Set cache type
-			Node cacheTypeNode = attributes.getNamedItem(CACHE_TYPE_ELEMENT);
-			if ((cacheTypeNode == null)
-					|| cacheTypeNode.getTextContent().equals(CACHE_VALUE_NONE)) {
-				cacheType = CACHE_TYPE_CACHE_NONE;
-			} else if (cacheTypeNode.getTextContent().equals(CACHE_VALUE_FILE)) {
-				cacheType = CACHE_TYPE_CACHE_FILE;
-			} else if (cacheTypeNode.getTextContent()
-					.equals(CACHE_VALUE_MEMORY)) {
-				cacheType = CACHE_TYPE_CACHE_MEMORY;
-			} else {
-				throw new IllegalArgumentException(
-						"Syntax error in the manifest, can not resolve resource cache type");
-			}
-
-			// Set locking policy
-			Node locking = attributes.getNamedItem(LOCKING_ELEMENT);
-			if (locking != null
-					&& locking.getTextContent().equals(LOCKED_VALUE)) {
-				lockingPolicy = E_XN_LOCKED;
-			}
-
-			// If EXnThemeStatusLicenceeDefault flag is set, locking policy is
-			// E_XN_LOCKED
-			if ((aManifest.getThemeStatus().intValue() & ThemeStatusResolver.E_XN_THEME_STATUS_LICENCEE_DEFAULT) != 0) {
-				lockingPolicy = E_XN_LOCKED;
-			}
-
-			// Resolve mime type
-			String mime = iMimeTypeResolver.getMimeType(filename);
-
-			// Resolve resource type
-			int resourceType = iMimeTypeResolver.getResourceType(filename);
-
-			// Verify language id
-			Node parent = node.getParentNode();
-			NamedNodeMap attr = parent.getAttributes();
-
-			// Language specific resources
-			if (attr.getLength() == 1
-					&& aLanguageId == Integer.valueOf(
-							attr.item(0).getNodeValue()).intValue()) {
-				ThemeResource resource = new ThemeResource(filename, cacheType,
-						lockingPolicy, aManifest.getNameSpace(), resourceType,
-						mime);
-				result.add(resource);
-			}
-			// Language independent resources
-			else if (aLanguageId == LANGUAGE_INDEPENDENT
-					&& !LANGUAGE_SPECIFIC_ELEMENT.equals(parent.getNodeName())) {
-				ThemeResource resource = new ThemeResource(filename, cacheType,
-						lockingPolicy, aManifest.getNameSpace(), resourceType,
-						mime);
-				result.add(resource);
-			}
-		}
-
-		return result;
-	}
-
-	/**
-	 * Checks that there exists just one node in the list
-	 * 
-	 * @param aNodeList
-	 *            Node list to be checked
-	 * @return Only one existing node
-	 * @throws IllegalArgumentException
-	 *             If there is more or less than one node in list
-	 */
-	private Node checkOneNode(NodeList aNodeList, String tagName) {
-
-		if (aNodeList.getLength() > 1) {
-			 throw new IllegalArgumentException(
-			 "Syntax error in manifest file, more child nodes than expected");
-		}
-		return aNodeList.item(0);
-	}
-
-	/**
-	 * Checks that there exists max one node in the list and it is language
-	 * independent.
-	 * 
-	 * @param aNodeList
-	 *            Node list to be checked
-	 * @return The existing language independent node or null
-	 * @throws IllegalArgumentException
-	 *             If there is more or less than one node in list
-	 */
-	private Node checkMaxOneLanguageIndependentNode(NodeList aNodeList) {
-		Node result = null;
-		int count = 0;
-		for (int i = 0; i < aNodeList.getLength(); i++) {
-			// Verify language in-dependency
-			Node node = aNodeList.item(i);
-			Node parent = node.getParentNode();
-			if (!LANGUAGE_SPECIFIC_ELEMENT.equals(parent.getNodeName())) {
-				result = node;
-				count++;
-			}
-		}
-
-		if (count > 1) {
-			throw new IllegalArgumentException(
-					"Syntax error in manifest file, more language "
-							+ "independent child nodes than expected");
-		}
-
-		return result;
-	}
-
-}