sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/ManageResources.java
changeset 0 522a326673b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/ManageResources.java	Thu Mar 11 19:08:43 2010 +0200
@@ -0,0 +1,642 @@
+// Copyright (c) 2008-2009 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:
+//
+
+package com.symbian.smt.gui;
+
+import static com.symbian.smt.gui.ResourcesEnums.BORDER_SHAPES;
+import static com.symbian.smt.gui.ResourcesEnums.BORDER_STYLES;
+import static com.symbian.smt.gui.ResourcesEnums.COLOURS;
+import static com.symbian.smt.gui.ResourcesEnums.DEPENDENCIES;
+import static com.symbian.smt.gui.ResourcesEnums.LEVELS;
+import static com.symbian.smt.gui.ResourcesEnums.LOCALISATION;
+import static com.symbian.smt.gui.ResourcesEnums.PATTERNS;
+import static com.symbian.smt.gui.ResourcesEnums.S12_XML;
+import static com.symbian.smt.gui.ResourcesEnums.SHAPES;
+import static com.symbian.smt.gui.ResourcesEnums.SYSTEM_INFO;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+
+public class ManageResources {
+
+	private static final List<String> RESOURCE_FOLDER_NAMES = Helper
+			.toListOfStrings(ResourcesEnums.values());
+
+	public static final String IS_URL = "isUrl";
+	public static final String URL_STRING = "urlString";
+
+	/**
+	 * Deletes a resource, if it exists within a specified folder within the
+	 * project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param folderName
+	 *            The folder in which the resource is to be updated
+	 * @return void
+	 */
+	private static void deleteResources(IProject project, String folderName) {
+		// Create/Get the folder in the project
+		IFolder folder = getFolderInProject(project, folderName);
+
+		try {
+			for (IResource res : folder.members()) {
+				res.delete(true, null);
+			}
+		} catch (CoreException e) {
+			Logger.log(e.getMessage(), e);
+		}
+	}
+
+	/**
+	 * Returns an IFolder object for the specified folder and project. Creates
+	 * the folder if it does not already exist.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param folderName
+	 *            The folder name required
+	 * @return IFolder
+	 */
+	private static IFolder getFolderInProject(IProject project,
+			String folderName) {
+		// Makes a folder in the project
+		final IFolder folder = project.getFolder(new Path(folderName));
+
+		// Check to see if the folder already exists before creating it
+		if (!folder.exists()) {
+			try {
+				folder.create(true, true, null);
+			} catch (CoreException e) {
+				Logger.log(e.getMessage(), e);
+			}
+		}
+		return folder;
+	}
+
+	/**
+	 * Creates and returns an AbstractPersistentDataStore object, used for
+	 * persising data.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @return AbstractPersistentDataStore
+	 */
+	private static AbstractPersistentDataStore getPersistDataStore(
+			IProject project) {
+		IScopeContext projectScope = new ProjectScope(project);
+		IEclipsePreferences node = projectScope.getNode(Activator.PLUGIN_ID);
+		AbstractPersistentDataStore dataStore = new PersistentDataStore(node);
+
+		return dataStore;
+	}
+
+	public static ResourcesEnums getResourceType(IFile file) {
+		if (isResourceFile(file)) {
+			String folderName = ((IFolder) file.getParent()).getName();
+
+			return ResourcesEnums.getResourcesEnums(folderName);
+		}
+
+		return null;
+	}
+
+	public static String getResourceUrl(IFile file) throws CoreException {
+		String urlString = null;
+		IMarker[] messageMarkers = file.findMarkers(IMarker.TASK, false,
+				IResource.DEPTH_ZERO);
+
+		for (int i = 0; i < messageMarkers.length; i++) {
+			IMarker marker = messageMarkers[i];
+
+			if (marker.getAttribute(ManageResources.IS_URL, false)) {
+				urlString = (String) marker.getAttribute(URL_STRING);
+			}
+		}
+
+		return urlString;
+	}
+
+	public static boolean isLocalPath(String path) {
+		int index = path.indexOf(':');
+
+		if (index == -1 || index == 1) {
+			return true;
+		} else if (index > 1) {
+			return false;
+		} else {
+			throw new RuntimeException("Unexpected file path format.");
+		}
+	}
+
+	public static boolean isResourceFile(IFile file) {
+		IContainer container = file.getParent();
+
+		if (container instanceof IFolder) {
+			IFolder folder = (IFolder) container;
+			String folderName = folder.getName();
+
+			if (RESOURCE_FOLDER_NAMES.contains(folderName)) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
+	public static boolean isSystemDefinitionFile(IFile file) {
+		IContainer container = file.getParent();
+
+		if (container instanceof IProject) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Adds a file shortcut to the specified project
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param folder
+	 *            The folder to create the shortcut in
+	 * @param filenameInOS
+	 *            The file in the OS to create the shortcut to
+	 * @param filenameInProject
+	 *            The name to use for the shortcut
+	 * @return void
+	 */
+	private static void makeFileShortcut(IProject project, String folder,
+			String filenameInOS, String fileNameInProject) {
+		IFile file;
+
+		// Check to see if the file needs to go into a folder and create the
+		// IFile object
+		if (folder == null || folder.length() == 0) {
+			file = project.getFile(fileNameInProject);
+		} else {
+			IFolder folder2 = project.getFolder(folder);
+			file = folder2.getFile(fileNameInProject);
+		}
+
+		// If the file is not being linked to a file in the OS then create a new
+		// empty file
+		if (filenameInOS == null || filenameInOS.length() == 0) {
+			filenameInOS = file.getRawLocation().toString();
+
+			File newEmptyFile = new File(filenameInOS);
+
+			try {
+				newEmptyFile.createNewFile();
+			} catch (IOException e) {
+				Logger.log(e.getMessage(), e);
+			}
+		}
+
+		// Create a link to the file
+		try {
+			if (isLocalPath(filenameInOS)) {
+				IPath path = new Path(filenameInOS);
+				file.createLink(path, IResource.ALLOW_MISSING_LOCAL, null);
+			} else {
+				file.create(null, false, null);
+				IMarker marker = file.createMarker(IMarker.TASK);
+				marker.setAttribute(IS_URL, true);
+				marker.setAttribute(URL_STRING, filenameInOS);
+			}
+
+			FileValidationHelper.validateSysDefFile(file);
+		} catch (CoreException e) {
+			Logger.log(e.getMessage(), e);
+		}
+	}
+
+	/**
+	 * Updates the border shapes file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateBorderShapesFiles(IProject project,
+			String[] options) {
+		updateResources(project, options, BORDER_SHAPES);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedBorderShapesFiles(options);
+	}
+
+	/**
+	 * Updates the border styles file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateBorderStylesFiles(IProject project,
+			String[] options) {
+		updateResources(project, options, BORDER_STYLES);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedBorderStylesFiles(options);
+	}
+
+	/**
+	 * Updates the colours file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateColoursFiles(IProject project, String[] options) {
+		updateResources(project, options, COLOURS);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedColoursFiles(options);
+	}
+
+	/**
+	 * Updates the dependencies file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateDependenciesFiles(IProject project,
+			String[] options) {
+		updateResources(project, options, DEPENDENCIES);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedDependenciesFiles(options);
+	}
+
+	/**
+	 * Updates the levels file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateLevelsFiles(IProject project, String[] options) {
+		updateResources(project, options, LEVELS);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedLevelsFiles(options);
+	}
+
+	/**
+	 * Updates the localisation file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateLocalisationFiles(IProject project,
+			String[] options) {
+		updateResources(project, options, LOCALISATION);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedLocalisationFiles(options);
+	}
+
+	/**
+	 * Updates the patterns file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updatePatternsFiles(IProject project, String[] options) {
+		updateResources(project, options, PATTERNS);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedPatternsFiles(options);
+	}
+
+	/**
+	 * Updates a resource within a specified folder within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param folderName
+	 *            The folder in which the resource is to be updated
+	 * @param option
+	 *            Either a filename or AUTO_LEVEL
+	 * @return void
+	 */
+	private static void updateResource(IProject project, String folderName,
+			String option) {
+		// The other arguments are checked by the callers
+		if (folderName == null) {
+			throw new IllegalArgumentException("Arguments cannot be null.");
+		}
+
+		// Create/Get the folder in the project
+		IFolder folder = getFolderInProject(project, folderName);
+
+		// If we were passed the empty string as the file name, just return,
+		// otherwise
+		// create the file
+		if (option.length() > 0) {
+			String newName;
+
+			if (isLocalPath(option)) {
+				String[] filenameParts = option.split("[\\\\/]");
+				newName = filenameParts[filenameParts.length - 1];
+			} else { // If option is a URL
+				int beginIndex = option.lastIndexOf("/");
+				newName = option.substring(beginIndex + 1, option.length());
+			}
+
+			if (!option.equals("Auto")) {
+				// Create a link to the file
+				try {
+					IFile file = folder.getFile(newName);
+					
+					if (isLocalPath(option)) {
+						IPath path = new Path(option);
+						file.createLink(path, IResource.ALLOW_MISSING_LOCAL, null);
+					}
+					else {
+						file.create(null, false, null);
+						IMarker marker = file.createMarker(IMarker.TASK);
+						marker.setAttribute(IS_URL, true);
+						marker.setAttribute(URL_STRING, option);
+					}
+
+					// TODO:BRS:Remove if test when Shapes.xsd is available
+					if (!folderName.equals("Shapes")) {
+						FileValidationHelper.validateResourceFile(file);
+					}
+				} catch (CoreException e) {
+					Logger.log(e.getMessage(), e);
+				}
+			}
+		}
+	}
+
+	private static void updateResources(IProject project, String[] options,
+			ResourcesEnums type) {
+		if (project == null || options == null) {
+			throw new IllegalArgumentException("Arguments cannot be null.");
+		}
+
+		String folderName = type.arg();
+
+		// First delete any existing resources from their folder
+		deleteResources(project, folderName);
+
+		// If options is empty, we simply need to invoke updateResource() with
+		// the empty
+		// String to ensure that the corresponding folder is created and then
+		// return.
+		if (options.length == 0) {
+			updateResource(project, folderName, "");
+			return;
+		}
+
+		for (String option : options) {
+			updateResource(project, folderName, option);
+		}
+	}
+
+	/**
+	 * Updates the S12 XML file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateS12XmlFiles(IProject project, String[] options) {
+		updateResources(project, options, S12_XML);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedS12XmlFiles(options);
+	}
+
+	/**
+	 * Updates the shapes file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateShapesFiles(IProject project, String[] options) {
+		updateResources(project, options, SHAPES);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedShapesFiles(options);
+
+	}
+
+	/**
+	 * Updates the system definition files within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param systemDefinitionFiles
+	 *            The system definition files to be used by the project
+	 * @param force
+	 *            Forces new shortcuts to be created in the project for the
+	 *            system definition files
+	 * @return void
+	 */
+	public static void updateSystemDefinitionFiles(IProject project,
+			String[] sysdefFiles, Boolean force) {
+		HashMap<String, Integer> systemDefinitionFiles = new HashMap<String, Integer>();
+
+		// Work out if we need to add any numbers to filenames to keep them
+		// unique
+		// It is not possible to have multiple files with the same name, so if
+		// this does happen a
+		// number is added to further instances, e.g afile, afile(2), afile(3)
+		// etc.
+		HashMap<String, Integer> systemDefinitionFilesCounts = new HashMap<String, Integer>();
+
+		java.util.regex.Pattern p = Pattern.compile("\\((\\d+)\\)\\.xml",
+				Pattern.CASE_INSENSITIVE);
+
+		try {
+			IResource[] members;
+			members = project.members();
+			for (IResource res : members) {
+
+				java.util.regex.Matcher m = p.matcher(res.getName());
+
+				if (m.find()) {
+					int num = Integer.valueOf(m.group(1));
+					String simpleName = m.replaceAll(".xml");
+					if (!systemDefinitionFilesCounts.containsKey(simpleName
+							.toLowerCase())
+							|| systemDefinitionFilesCounts.get(simpleName
+									.toLowerCase()) < ++num) {
+						systemDefinitionFilesCounts.put(simpleName
+								.toLowerCase(), ++num);
+					}
+				} else {
+					if (!systemDefinitionFilesCounts.containsKey(res.getName()
+							.toLowerCase())) {
+						systemDefinitionFilesCounts.put(res.getName()
+								.toLowerCase(), 2);
+					}
+				}
+			}
+		} catch (CoreException e) {
+			e.printStackTrace();
+		}
+
+		// Get the existing system definition files and put them into a hashmap
+		IScopeContext projectScope = new ProjectScope(project);
+		PersistentDataStore projectStore = new PersistentDataStore(projectScope
+				.getNode(Activator.PLUGIN_ID));
+
+		for (String sysdefFile : projectStore.getSystemDefinitionFiles()) {
+			systemDefinitionFiles.put(sysdefFile.toLowerCase(), 0);
+		}
+
+		for (String sysdefFile : sysdefFiles) {
+			// If the sysdef file has not been added or removed set to 1
+			if (systemDefinitionFiles.containsKey(sysdefFile.toLowerCase())
+					&& force != true) {
+				systemDefinitionFiles.put(sysdefFile.toLowerCase(), 1);
+			}
+			// Otherwise the file must be a new file
+			else {
+				systemDefinitionFiles.put(sysdefFile.toLowerCase(), 2);
+			}
+		}
+
+		for (String sysdefFile : systemDefinitionFiles.keySet()) {
+			// All files with a value of 0 must be deleted
+			if (systemDefinitionFiles.get(sysdefFile) == 0) {
+				IResource[] members;
+
+				try {
+					members = project.members();
+
+					for (IResource res : members) {
+						if (isLocalPath(sysdefFile)) {
+							if (res.isLinked()) {
+								if (sysdefFile.equalsIgnoreCase(res
+										.getRawLocation().toOSString())) {
+									res.delete(true, null);
+								}
+							}
+						} else { // If it is a URL
+							if (res instanceof IFile) {
+								String urlString = getResourceUrl((IFile) res);
+
+								if (urlString != null
+										&& sysdefFile
+												.equalsIgnoreCase(urlString)) {
+									res.delete(true, null);
+								}
+							}
+						}
+					}
+
+				} catch (CoreException e) {
+					Logger.log(e.getMessage(), e);
+				}
+			} else if (systemDefinitionFiles.get(sysdefFile.toLowerCase()) == 2) {
+				// All files with a value if 2 must be added
+				String newName;
+
+				if (isLocalPath(sysdefFile)) {
+					String[] filenameParts = sysdefFile.split("[\\\\/]");
+					newName = filenameParts[filenameParts.length - 1];
+				} else { // If option is a URL
+					int beginIndex = sysdefFile.lastIndexOf("/");
+					newName = sysdefFile.substring(beginIndex + 1, sysdefFile
+							.length());
+				}
+
+				int i = 1;
+
+				if (systemDefinitionFilesCounts.containsKey(newName
+						.toLowerCase())) {
+					i = systemDefinitionFilesCounts.get(newName.toLowerCase());
+
+					newName = newName.substring(0, newName.length() - 4)
+							+ "("
+							+ i
+							+ ")"
+							+ newName.substring(newName.length() - 4, newName
+									.length());
+				}
+
+				systemDefinitionFilesCounts.put(newName.toLowerCase(), ++i);
+
+				makeFileShortcut(project, null, sysdefFile, newName);
+			}
+			// Files with a value of 1 are unchanged so are ignored
+		}
+
+		// Persist the system definition files
+		projectStore.setSystemDefinitionFiles(sysdefFiles);
+	}
+
+	/**
+	 * Updates the system info file resources within the project.
+	 * 
+	 * @param project
+	 *            The project to amend
+	 * @param options
+	 *            An array of filenames or the empty array if there are no files
+	 * @return void
+	 */
+	public static void updateSystemInfoFiles(IProject project, String[] options) {
+		updateResources(project, options, SYSTEM_INFO);
+
+		// persist the data
+		getPersistDataStore(project).setSelectedSystemInfoFiles(options);
+	}
+
+}