diff -r 000000000000 -r 522a326673b6 sysmodelmgr/com.symbian.smt.gui/src/com/symbian/smt/gui/ManageResources.java --- /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 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 systemDefinitionFiles = new HashMap(); + + // 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 systemDefinitionFilesCounts = new HashMap(); + + 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); + } + +}