Java tutorial
/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.ui.wizards; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Field; import java.net.URI; import net.rim.ejde.internal.core.IConstants; import net.rim.ejde.internal.util.FileUtils; import net.rim.ejde.internal.util.ImportUtils; import net.rim.ejde.internal.util.Messages; import net.rim.ejde.internal.util.PackageUtils; import net.rim.ejde.internal.util.ProjectUtils; import net.rim.sdk.resourceutil.ResourceCollection; import net.rim.sdk.resourceutil.ResourceCollectionFactory; import net.rim.sdk.resourceutil.ResourceConstants; import net.rim.sdk.resourceutil.ResourceElement; import net.rim.sdk.resourceutil.ResourceLocale; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.ui.dialogs.WizardNewFileCreationPage; import org.eclipse.ui.internal.ide.dialogs.CreateLinkedResourceGroup; /** * This page is used to create and link new resource files. * * @author jkeshavarzi */ public class NewResourceFileWizardPage extends WizardNewFileCreationPage { private String _resourcePackageId; private boolean _validPackage; private static final Logger logger = Logger.getLogger(NewResourceFileWizardPage.class); private IPackageFragment _userSelectedPackage; private IPackageFragmentRoot _userSelectedSourceFolder; private String _userSelectedProject; private URI linkFileLocation; /** * Constructs a new resource wizard page. */ public NewResourceFileWizardPage(IStructuredSelection selection) { super("NewResourceFileWizardPage", selection); //$NON-NLS-1$ setTitle(Messages.NewResourceFileWizardNewProjectTitle); setDescription(Messages.NewResourceFileWizardDescription); } /** * This method returns the resource package id. * * @return A string containing the package id. */ public String getResourcePackageId() { return _resourcePackageId; } /** * @return the package selected by the user within the new resource dialog */ public IPackageFragment getUserSelectedPackage() { return _userSelectedPackage; } /** * @return the source folder selected by the user within the new resource dialog */ public IPackageFragmentRoot getUserSelectedSourceFolder() { return _userSelectedSourceFolder; } /** * @return the project selected by the user within the new resource dialog */ public String getUserSelectedProject() { return _userSelectedProject; } /** * This method returns whether the package selected is valid. * * @return True is the package is valid, false otherwise. */ public boolean isValidPackage() { return _validPackage; } @Override protected boolean validatePage() { // perform preliminary page validation with // WizardNewFileCreationPage.validatePage() method boolean validPage = super.validatePage(); if (validPage) { if (!getFileName().matches("([A-Za-z0-9]+([_][A-Za-z0-9]+){0,2}.rrc)|([A-Za-z0-9]+.rrh)")) { setErrorMessage(Messages.INVALID_FILE_NAME); validPage = false; } } if (validPage) { /* ensures the user selected a package under an eclipse source directory */ boolean sourceFolderExists = false; _userSelectedProject = getContainerFullPath().segment(0); String path = getContainerFullPath().toString(); IPackageFragmentRoot sourceRoots[] = ProjectUtils .getProjectSourceFolders(ProjectUtils.getProject(_userSelectedProject)); // Iterate through all source folders for (IPackageFragmentRoot sourceRoot : sourceRoots) { String sourcePath = sourceRoot.getPath().toString() + IPath.SEPARATOR; if (path.startsWith(sourcePath) && (path.length() > sourcePath.length())) { String selectedPackage = path.substring(sourcePath.length()).replaceAll("/", "."); //$NON-NLS-1$ //$NON-NLS-2$ // Since our current code standard is 1.5 do not use 1.6 methods yet. if (!StringUtils.isEmpty(selectedPackage) && sourceRoot.getPackageFragment(selectedPackage).exists()) { sourceFolderExists = true; _userSelectedPackage = sourceRoot.getPackageFragment(selectedPackage); _userSelectedSourceFolder = sourceRoot; break; } } } if (!sourceFolderExists) { setErrorMessage(Messages.INVALID_PARENT_FOLDER_WIZARD_PAGE); validPage = false; } } if (validPage) { try { /* * Here we get access to the private field linkedResourceGroup and get the URI information for the linked .rrh * file. We then parse that file to get its package information */ Field field = WizardNewFileCreationPage.class.getDeclaredField("linkedResourceGroup"); //$NON-NLS-1$ field.setAccessible(true); linkFileLocation = ((CreateLinkedResourceGroup) field.get(this)).getLinkTargetURI(); // If file is not linked, skip next code. if (linkFileLocation == null) { _validPackage = true; } else { // Initialize the resourcePackageID to properly identify if the package is valid _resourcePackageId = null; File linkFile = new File(linkFileLocation); if (getFileName().endsWith(ResourceConstants.RRH_SUFFIX)) { /* * Resource file is a rrh file. We must determine if its going in the correct package. */ if (linkFile.length() == 0) { setErrorMessage(Messages.RRH_NO_PACKAGE_ERROR); return false; } _resourcePackageId = PackageUtils.getRRHPackageID(linkFile); } else { /* * Resource file is a rrc file. We must determine the correct package with its corresponding rrh file. */ String rrhFileName = getFileName(); if (rrhFileName.contains("_")) { //$NON-NLS-1$ rrhFileName = rrhFileName.substring(0, rrhFileName.indexOf("_")) //$NON-NLS-1$ + ResourceConstants.RRH_SUFFIX; } else { rrhFileName = rrhFileName.replace(ResourceConstants.RRC_SUFFIX, ResourceConstants.RRH_SUFFIX); } File rrhFile = new File(linkFile.getParent() + File.separator + rrhFileName); if (rrhFile.exists() && (rrhFile.length() != 0)) { _resourcePackageId = PackageUtils.getRRHPackageID(rrhFile); } } /* * Get package selected by user within the new resource wizard dialog and ensure it matches the package * described in the .rrh file. */ _userSelectedProject = getContainerFullPath().segment(0); if (_resourcePackageId == null) { /* * Resource header file could not be found or contains no package. Ensuring correct package will have to * be left to user. */ _validPackage = true; } else if (!_resourcePackageId.equals(_userSelectedPackage.getElementName())) { setMessage(NLS.bind(Messages.INVALID_PACKAGE_SELECTED, _resourcePackageId), IMessageProvider.WARNING); _validPackage = false; } else { _validPackage = true; } } } catch (Throwable e) { logger.error("Validation Error", e); //$NON-NLS-1$ } } if (validPage) { // Add warning if existing sibling resource exist IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(_userSelectedProject); IFile foundSiblingFile = getSiblingFile(getFileName(), project); if (foundSiblingFile != null) { if (foundSiblingFile.isLinked()) { setMessage(NLS.bind(Messages.EXISTING_LINKED_SIBLING_FOUND_WARNING, foundSiblingFile.getName(), getFileName()), IMessageProvider.WARNING); } else { setMessage(NLS.bind(Messages.EXISTING_COPIED_SIBLING_FOUND_WARNING, foundSiblingFile.getName(), getFileName()), IMessageProvider.WARNING); } } } return validPage; } private IFile getSiblingFile(String fileName, IProject project) { String rrhFileName = null; String rrcRootLocaleFileName = null; String rrcRootLanguageLocaleFileName = null; String siblingFileName = null; String fileNamePrefix = null; IFile foundSiblingFile = null; boolean hasCountryCode = (fileName.indexOf(IConstants.UNDERSCORE_STRING) != fileName .lastIndexOf(IConstants.UNDERSCORE_STRING)); if (fileName.contains(IConstants.UNDERSCORE_STRING)) { rrhFileName = fileName.substring(0, fileName.indexOf(IConstants.UNDERSCORE_STRING)) + ResourceConstants.RRH_SUFFIX; // set root rrc file name rrcRootLocaleFileName = fileName.substring(0, fileName.indexOf(IConstants.UNDERSCORE_STRING)) + ResourceConstants.RRC_SUFFIX; if (hasCountryCode) { // set root language rrc file name rrcRootLanguageLocaleFileName = fileName.substring(0, fileName.lastIndexOf(IConstants.UNDERSCORE_STRING)) + ResourceConstants.RRC_SUFFIX; } } else { rrhFileName = fileName.substring(0, fileName.lastIndexOf(IConstants.DOT_MARK)) + ResourceConstants.RRH_SUFFIX; rrcRootLocaleFileName = fileName.substring(0, fileName.lastIndexOf(IConstants.DOT_MARK)) + ResourceConstants.RRC_SUFFIX; } if (fileName.endsWith(ResourceConstants.RRH_SUFFIX)) { siblingFileName = rrcRootLocaleFileName; foundSiblingFile = ProjectUtils.getProjectIFile(project, siblingFileName, false); if (foundSiblingFile == null) { fileNamePrefix = fileName.substring(0, fileName.lastIndexOf(IConstants.DOT_MARK)) + IConstants.UNDERSCORE_STRING; foundSiblingFile = ProjectUtils.getProjectIFile(project, fileNamePrefix, false); siblingFileName = foundSiblingFile == null ? null : foundSiblingFile.getName(); } } else { siblingFileName = rrhFileName; foundSiblingFile = ProjectUtils.getProjectIFile(project, siblingFileName, false); if (foundSiblingFile == null) { siblingFileName = rrcRootLocaleFileName; foundSiblingFile = ProjectUtils.getProjectIFile(project, siblingFileName, false); } if (foundSiblingFile == null) { siblingFileName = rrcRootLanguageLocaleFileName; foundSiblingFile = ProjectUtils.getProjectIFile(project, siblingFileName, false); } if (foundSiblingFile == null) { if (fileName.contains(IConstants.UNDERSCORE_STRING)) { fileNamePrefix = fileName.substring(0, fileName.indexOf(IConstants.UNDERSCORE_STRING)) + IConstants.UNDERSCORE_STRING; } else { fileNamePrefix = fileName.substring(0, fileName.lastIndexOf(IConstants.DOT_MARK)) + IConstants.UNDERSCORE_STRING; } foundSiblingFile = ProjectUtils.getProjectIFile(project, fileNamePrefix, false); siblingFileName = foundSiblingFile == null ? null : foundSiblingFile.getName(); } } return foundSiblingFile; } // This method was overwritten to provide fix for DPI222448 and some // new functionality. @Override public IFile createNewFile() { String fileName = this.getFileName(); IFile newResourceFile = null; IPath resFilePath = null; IPath resParentPath = null; String rrcRootLocaleFileName = null; String rrcRootLanguageLocaleFileName = null; IFile siblingIFile = null; String pkgString = null; boolean hasCountryCode = (fileName.indexOf(IConstants.UNDERSCORE_STRING) != fileName .lastIndexOf(IConstants.UNDERSCORE_STRING)); if (fileName.contains(IConstants.UNDERSCORE_STRING)) { // set root rrc file name rrcRootLocaleFileName = fileName.substring(0, fileName.indexOf(IConstants.UNDERSCORE_STRING)) + ResourceConstants.RRC_SUFFIX; if (hasCountryCode) { // set root language rrc file name rrcRootLanguageLocaleFileName = fileName.substring(0, fileName.lastIndexOf(IConstants.UNDERSCORE_STRING)) + ResourceConstants.RRC_SUFFIX; } } else { rrcRootLocaleFileName = fileName.substring(0, fileName.lastIndexOf(IConstants.DOT_MARK)) + ResourceConstants.RRC_SUFFIX; } IProject iProject = ProjectUtils.getProject(_userSelectedProject); siblingIFile = getSiblingFile(fileName, iProject); String userSelectedPackage = null; try { if ((siblingIFile != null) && siblingIFile.exists()) { // sibling file is found in the rim project but not under // the same directory. Possibly file is linked from another // place. resFilePath = siblingIFile.getLocation(); File siblingFile = new File(resFilePath.toOSString()); resParentPath = resFilePath.removeLastSegments(1); resFilePath = resParentPath.append(fileName); // even though user selects the improper package // we will match the right package based on // sibling file package string if (siblingIFile.getName().endsWith(ResourceConstants.RRH_SUFFIX)) { pkgString = PackageUtils.getRRHPackageString(siblingFile); } else { File rrhFile = PackageUtils.getCorrespondingRRHFile(siblingFile); // eg:- com.rim.test userSelectedPackage = _userSelectedPackage.getElementName(); // eg:- com/rim/test userSelectedPackage = PackageUtils.convertPkgIDToString(userSelectedPackage); if (!rrhFile.exists()) { pkgString = userSelectedPackage; } else { try { pkgString = PackageUtils.getRRCPackageString(siblingFile); } catch (CoreException e) { // we don't need to log the error here - method already logging the error pkgString = userSelectedPackage; } } } // special case when user try to link resource // file with country code // (Res1_en_CA.rrc) in the linked location // but rrcRootLocaleFileName and // rrcRootLanguageLocaleFileName is missing in // that directory will be an error. So we need // to create those files and linked them as // well. File newRootFile = null; if (!StringUtils.isBlank(rrcRootLocaleFileName)) { newRootFile = new File(resParentPath.append(rrcRootLocaleFileName).toOSString()); if (!newRootFile.exists()) { newRootFile.createNewFile(); } } File newRootLangLocaleFile = null; if (!StringUtils.isBlank(rrcRootLanguageLocaleFileName)) { newRootLangLocaleFile = new File( resParentPath.append(rrcRootLanguageLocaleFileName).toOSString()); if (!newRootLangLocaleFile.exists()) { newRootLangLocaleFile.createNewFile(); } } File newFile = resFilePath.toFile(); if (!newFile.exists()) { String newFileName = newFile.getName(); newFile = new File(resFilePath.toOSString()); File existingFile = null; if (linkFileLocation != null) { existingFile = new File(linkFileLocation); } if ((existingFile != null) && existingFile.exists()) { FileUtils.copy(existingFile, newFile); ResourceCollection collection = ResourceCollectionFactory .newResourceCollection(newFile.getAbsolutePath()); if (newFileName.endsWith(ResourceConstants.RRH_SUFFIX)) { ResourceLocale existingLocales[] = collection.getLocales(); for (ResourceLocale locale : existingLocales) { addMissingLocaleKeys(collection, locale); } } else { String localeName = newFileName.substring(newFileName.indexOf("_") + 1, //$NON-NLS-1$ newFileName.lastIndexOf(".")); //$NON-NLS-1$ ResourceLocale newLocale = collection.getLocale(localeName); if (newLocale != null) { addMissingLocaleKeys(collection, newLocale); } } } else { newFile.createNewFile(); if (newFileName.endsWith(ResourceConstants.RRH_SUFFIX)) { // rrh file must have a package declaration PrintWriter out = new PrintWriter(new FileWriter(newFile)); out.println("package " + PackageUtils.convertPkgStringToID(pkgString) + ";"); out.close(); } } } if (siblingIFile.isLinked()) { IPath sourceLocation = _userSelectedSourceFolder.getCorrespondingResource() .getProjectRelativePath().append(pkgString); IContainer parentFolder = iProject.getFolder(sourceLocation); if (newRootFile != null) { IFile linkRootFile = parentFolder.getFile(new Path(rrcRootLocaleFileName)); if (!linkRootFile.exists()) { linkRootFile.createLink(new Path(newRootFile.getAbsolutePath()), IResource.NONE, new NullProgressMonitor()); } } if (newRootLangLocaleFile != null) { IFile linkRootLangFile = parentFolder.getFile(new Path(rrcRootLanguageLocaleFileName)); if (!linkRootLangFile.exists()) { linkRootLangFile.createLink(new Path(newRootLangLocaleFile.getAbsolutePath()), IResource.NONE, new NullProgressMonitor()); } } IFile linkFile = parentFolder.getFile(new Path(fileName)); if (!linkFile.exists()) { linkFile.createLink(resFilePath, IResource.NONE, new NullProgressMonitor()); newResourceFile = linkFile; } } else { iProject.refreshLocal(IProject.DEPTH_INFINITE, new NullProgressMonitor()); newResourceFile = ImportUtils.getProjectBasedFileFromOSBasedFile(_userSelectedProject, newFile.getAbsolutePath()); } } else { // Sibling file does not exists in the linked // location.At this point we have no clue where // to link, so it is better to create the file // in eclipse workspace. } if (newResourceFile == null) { super.setFileName(super.getFileName().trim()); newResourceFile = super.createNewFile(); } } catch (Throwable e) { logger.error("createNewFile() error", e); //$NON-NLS-1$ } return newResourceFile; } /** * This method will add any keys found in the locale but not in the header file to the header file. * * @param collection * - The collection to add missing keys to. * @param newLocale * - The locale to check for keys. */ private void addMissingLocaleKeys(ResourceCollection collection, ResourceLocale locale) { ResourceElement elements[] = locale.getResourceElements(); String key = null; for (ResourceElement element : elements) { key = element.getKey(); if (!collection.containsKey(key)) { collection.addKey(key); } } try { collection.save(); } catch (IOException e) { logger.error("addMissingLocaleKeys() error", e); //$NON-NLS-1$ } } }