net.rim.ejde.internal.ui.wizards.NewResourceFileWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for net.rim.ejde.internal.ui.wizards.NewResourceFileWizardPage.java

Source

/*
* 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$
        }
    }

}