/* * 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.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.lang.reflect.Field; import net.rim.ejde.internal.core.ContextManager; import net.rim.ejde.internal.util.Messages; import net.rim.ejde.internal.util.ProjectUtils; import net.rim.sdk.resourceutil.ResourceConstants; import org.apache.log4j.Logger; 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.jdt.core.IJavaElement; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.wizard.Wizard; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.dialogs.WizardNewFileCreationPage; import org.eclipse.ui.internal.ide.misc.ContainerSelectionGroup; import org.eclipse.ui.internal.ide.misc.ResourceAndContainerGroup; /** * The wizard for creating new .rrh header and .rrc content resource files. Normally, it can be accessed via the menu by File > * New > Other... > BlackBerry > BlackBerry Resource File. * * @author edwong, jkeshavarzi * */ public class NewResourceFileWizard extends Wizard implements INewWizard { protected IWorkbench workbench; private IStructuredSelection selection; private NewResourceFileWizardPage newResourceFileCreationPage; private static final Logger logger = Logger.getLogger( NewResourceFileWizard.class ); //public static final String WIZARD_ID = "net.rim.eide.ui.wizards.WorkspaceNewProjectWizard"; //$NON-NLS-1$ public NewResourceFileWizard() { super(); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection) */ public void init( IWorkbench workbench, IStructuredSelection selection ) { this.workbench = workbench; this.selection = selection; setWindowTitle( Messages.newResourceFileWindowsTitle ); //$NON-NLS-1$ setDefaultPageImageDescriptor( ContextManager.imageDescriptorFromPlugin( ContextManager.PLUGIN_ID, Messages.IMAGE_DESCRIPTOR_FILE_PATH ) ); } /* * (non-Javadoc) * * @see org.eclipse.jface.wizard.Wizard#addPages() */ public void addPages() { if( selection != null ) { newResourceFileCreationPage = new NewResourceFileWizardPage( selection ); } else { newResourceFileCreationPage = new NewResourceFileWizardPage( new StructuredSelection() ); } addPage( newResourceFileCreationPage ); } private String createPackageStatement( IPackageFragment userSelectedPackage ) { StringBuffer packageStatementBuffer = new StringBuffer(); packageStatementBuffer.append( "package " ); //$NON-NLS-1$ packageStatementBuffer.append( userSelectedPackage.getElementName() ); packageStatementBuffer.append( ";" ); //$NON-NLS-1$ return packageStatementBuffer.toString(); } /* * (non-Javadoc) * * @see org.eclipse.jface.wizard.Wizard#performFinish() */ @Override public boolean performFinish() { final IProject userSelectedProject = ProjectUtils.getProject( newResourceFileCreationPage.getUserSelectedProject() ); String fileName = newResourceFileCreationPage.getFileName(); IFile newResourceFile = null; IPackageFragmentRoot userSelectedSourceFolder = newResourceFileCreationPage.getUserSelectedSourceFolder(); IPackageFragment userSelectedPackage = newResourceFileCreationPage.getUserSelectedPackage(); String _resourcePackageId = newResourceFileCreationPage.getResourcePackageId(); if( newResourceFileCreationPage.isValidPackage() ) { // Package is valid. No need to find or create a package. newResourceFile = newResourceFileCreationPage.createNewFile(); } else { // Package selected is invalid. First we try and find package within // project workspace. IPackageFragmentRoot sourceRoots[] = ProjectUtils.getProjectSourceFolders( userSelectedProject ); try { IJavaElement foundPackageElement = null; for( IPackageFragmentRoot sourceRoot : sourceRoots ) { IPackageFragment packageFragment = sourceRoot.getPackageFragment( _resourcePackageId ); if( packageFragment.exists() ) { foundPackageElement = packageFragment; break; } } if( foundPackageElement == null ) { // Package could not be found. We must create the package. IPackageFragment newlyCreatedPackage = userSelectedSourceFolder.createPackageFragment( _resourcePackageId, true, null ); /* * The following code uses reflection to access a private TreeViewer. I had to work through multiple levels of * objects to access the private field. In the future this code can break, if the hierarchy for these classes * or the names of these fields change. Once i access the TreeViewer i then refresh it. This allows the newly * created package to be added to the Tree and prevents a NullPointerException. */ Field fieldToAccess = WizardNewFileCreationPage.class.getDeclaredField( "resourceGroup" ); //$NON-NLS-1$ fieldToAccess.setAccessible( true ); ResourceAndContainerGroup resourceGroup = ( (ResourceAndContainerGroup) fieldToAccess .get( newResourceFileCreationPage ) ); fieldToAccess = ResourceAndContainerGroup.class.getDeclaredField( "containerGroup" ); //$NON-NLS-1$ fieldToAccess.setAccessible( true ); ContainerSelectionGroup containerGroup = ( (ContainerSelectionGroup) fieldToAccess.get( resourceGroup ) ); fieldToAccess = ContainerSelectionGroup.class.getDeclaredField( "treeViewer" ); //$NON-NLS-1$ fieldToAccess.setAccessible( true ); TreeViewer treeViewer = ( (TreeViewer) fieldToAccess.get( containerGroup ) ); treeViewer.refresh(); /* * This code will set the container path to null if the above tree isn't refreshed when the package is * created. */ newResourceFileCreationPage.setContainerFullPath( newlyCreatedPackage.getPath() ); } else { // Package was found in project. Change the container path // to the found package. newResourceFileCreationPage.setContainerFullPath( foundPackageElement.getPath() ); } newResourceFile = newResourceFileCreationPage.createNewFile(); } catch( Throwable e ) { logger.error( "performFinish() error", e ); //$NON-NLS-1$ } } // if resource file is linked, we just return. Fix SDR213684 if( newResourceFile.isLinked() ) { return true; } String packageStmt = createPackageStatement( userSelectedPackage ); FileOutputStream fout = null; try { if( fileName.endsWith( ResourceConstants.RRH_SUFFIX ) ) { // user enters .rrh file extension // 1. create package statement File resourceFile = newResourceFile.getLocation().toFile(); if( resourceFile.length() == 0 && resourceFile.canWrite() ) { fout = new FileOutputStream( resourceFile ); new PrintStream( fout ).println( packageStmt ); } // 2. create associated .rrc root locale file if it doesn't // exist String rrcFileName = fileName.substring( 0, fileName.lastIndexOf( "." ) ) + ResourceConstants.RRC_SUFFIX; //$NON-NLS-1$ File rrcOSFile = new File( newResourceFile.getLocation().toFile().getParentFile(), rrcFileName ); if( !rrcOSFile.exists() ) { rrcOSFile.createNewFile();// TO->JDP } } if( fileName.endsWith( ResourceConstants.RRC_SUFFIX ) ) { // user enters .rrc file extension // if corresponding rrh file doesn't exist, create it and set // package statement // if corresponding .rrc root locale file doesn't exist, create // it as well String rrhFileName; String rrcRootLocaleFileName = null; String rrcRootLanguageLocaleFileName = null; boolean hasCountryCode = ( fileName.indexOf( "_" ) != fileName.lastIndexOf( "_" ) ); //$NON-NLS-1$ //$NON-NLS-2$ if( fileName.contains( "_" ) ) { //$NON-NLS-1$ rrhFileName = fileName.substring( 0, fileName.indexOf( "_" ) ) + ResourceConstants.RRH_SUFFIX; //$NON-NLS-1$ // set root rrc file name rrcRootLocaleFileName = fileName.substring( 0, fileName.indexOf( "_" ) ) + ResourceConstants.RRC_SUFFIX; //$NON-NLS-1$ if( hasCountryCode ) { // set root language rrc file name rrcRootLanguageLocaleFileName = fileName.substring( 0, fileName.lastIndexOf( "_" ) ) + ResourceConstants.RRC_SUFFIX; //$NON-NLS-1$ } } else { rrhFileName = fileName.substring( 0, fileName.lastIndexOf( "." ) ) + ResourceConstants.RRH_SUFFIX; //$NON-NLS-1$ } File rrhOSFile = new File( newResourceFile.getLocation().toFile().getParentFile(), rrhFileName ); if( !rrhOSFile.exists() ) { rrhOSFile.createNewFile();// // TO->JDP if( rrhOSFile.length() == 0 && rrhOSFile.canWrite() ) { fout = new FileOutputStream( rrhOSFile ); new PrintStream( fout ).println( packageStmt ); } } File rrcOSFile = null; // create .rrc root locale file if required if( rrcRootLocaleFileName != null ) { rrcOSFile = new File( newResourceFile.getLocation().toFile().getParentFile(), rrcRootLocaleFileName ); if( !rrcOSFile.exists() ) { rrcOSFile.createNewFile(); } } // create .rrc root language locale file if required if( rrcRootLanguageLocaleFileName != null ) { rrcOSFile = new File( newResourceFile.getLocation().toFile().getParentFile(), rrcRootLanguageLocaleFileName ); if( !rrcOSFile.exists() ) { rrcOSFile.createNewFile(); } } } } catch( Exception e ) { logger.error( "performFinish: Error creating file", e ); //$NON-NLS-1$ return false; } finally { try { if( null != fout ) fout.close(); } catch( IOException e ) { logger.error( "performFinish: Could not close the file", e ); //$NON-NLS-1$ } } // Fix for DPI224873. Project becomes out of sync, which results // in out // of sync errors. The below will refresh project. try { userSelectedProject.refreshLocal( IResource.DEPTH_INFINITE, new NullProgressMonitor() ); } catch( CoreException e ) { logger.error( "performFinish: Error during project refresh", e ); //$NON-NLS-1$ } return true; } protected IFile createExtraNewFile( String fileName ) { final IPath containerPath = newResourceFileCreationPage.getContainerFullPath(); IPath newFilePath = containerPath.append( fileName ); final IFile newFileHandle = ResourcesPlugin.getWorkspace().getRoot().getFile( newFilePath ); return newFileHandle; } }