--- /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);
+ }
+
+}