/** * <p>Copyright: Copyright (c) 2009</p> * <p>Company: �������ӹɷ����޹�˾</p> */ package com.hundsun.ares.studio.ui.wizard; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.StringTokenizer; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExecutableExtension; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveRegistry; import org.eclipse.ui.IPluginContribution; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.activities.IActivityManager; import org.eclipse.ui.activities.IIdentifier; import org.eclipse.ui.activities.IWorkbenchActivitySupport; import org.eclipse.ui.activities.WorkbenchActivityHelper; import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.ide.undo.CreateProjectOperation; import org.eclipse.ui.ide.undo.WorkspaceUndoUtil; import org.eclipse.ui.internal.IPreferenceConstants; import org.eclipse.ui.internal.WorkbenchPlugin; import org.eclipse.ui.internal.ide.IDEInternalPreferences; import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; import org.eclipse.ui.internal.ide.StatusUtil; import org.eclipse.ui.internal.registry.PerspectiveDescriptor; import org.eclipse.ui.internal.util.PrefUtil; import org.eclipse.ui.internal.wizards.newresource.ResourceMessages; import org.eclipse.ui.statushandlers.StatusAdapter; import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; import com.hundsun.ares.studio.core.IResPathEntry; import com.hundsun.ares.studio.core.util.ResourcesUtil; import com.hundsun.ares.studio.core.util.Util; import com.hundsun.ares.studio.ui.ARESUI; import com.hundsun.ares.studio.ui.template.Template; /** * �½�ģ�幤���� * @author sundl */ public class NewTemplateProjectWizard extends BasicNewResourceWizard implements INewWizard, IExecutableExtension{ private static Logger logger = Logger.getLogger(NewTemplateProjectWizard.class); /** * The wizard id for creating new projects in the workspace. * @since 3.4 */ public static final String WIZARD_ID = "com.hundsun.ares.studio.ui.wizard.temmplateproject"; //$NON-NLS-1$ private WizardNewProjectCreationPage mainPage; private TemplateSelectWizardPage templatePage; // cache of newly-created project private IProject newProject; /** * The config element which declares this wizard. */ private IConfigurationElement configElement; private static String WINDOW_PROBLEMS_TITLE = ResourceMessages.NewProject_errorOpeningWindow; /** * Extension attribute name for final perspective. */ private static final String FINAL_PERSPECTIVE = "finalPerspective"; //$NON-NLS-1$ /** * Extension attribute name for preferred perspectives. */ private static final String PREFERRED_PERSPECTIVES = "preferredPerspectives"; //$NON-NLS-1$ /** * Creates a wizard for creating a new project resource in the workspace. */ public NewTemplateProjectWizard() { IDialogSettings workbenchSettings = ARESUI.getDefault().getDialogSettings(); IDialogSettings section = workbenchSettings.getSection("NewTemplateProjectResourceWizard");//$NON-NLS-1$ if (section == null) { section = workbenchSettings.addNewSection("NewTemplateProjectResourceWizard");//$NON-NLS-1$ } setDialogSettings(section); } /* * (non-Javadoc) Method declared on IWizard. */ public void addPages() { super.addPages(); mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") { //$NON-NLS-1$ /* * (non-Javadoc) * * @see org.eclipse.ui.dialogs.WizardNewProjectCreationPage#createControl(org.eclipse.swt.widgets.Composite) */ public void createControl(Composite parent) { super.createControl(parent); createWorkingSetGroup( (Composite) getControl(), getSelection(), new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$ Dialog.applyDialogFont(getControl()); } }; mainPage.setTitle(ResourceMessages.NewProject_title); mainPage.setDescription(ResourceMessages.NewProject_description); this.addPage(mainPage); templatePage = new TemplateSelectWizardPage(); this.addPage(templatePage); } /** * Creates a new project resource with the selected name. * <p> * In normal usage, this method is invoked after the user has pressed Finish * on the wizard; the enablement of the Finish button implies that all * controls on the pages currently contain valid values. * </p> * <p> * Note that this wizard caches the new project once it has been * successfully created; subsequent invocations of this method will answer * the same project resource without attempting to create it again. * </p> * * @return the created project resource, or <code>null</code> if the * project was not created */ private IProject createNewProject() { if (newProject != null) { return newProject; } // get a project handle final IProject newProjectHandle = mainPage.getProjectHandle(); // get a project descriptor URI location = null; if (!mainPage.useDefaults()) { location = mainPage.getLocationURI(); } IWorkspace workspace = ResourcesPlugin.getWorkspace(); final IProjectDescription description = workspace .newProjectDescription(newProjectHandle.getName()); description.setLocationURI(location); // create the new project operation IRunnableWithProgress op = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException { CreateProjectOperation op = new CreateProjectOperation( description, ResourceMessages.NewProject_windowTitle) { @Override protected void doExecute(IProgressMonitor monitor, IAdaptable uiInfo) throws CoreException { super.doExecute(monitor, uiInfo); String projectName = description.getName(); Template template = templatePage.getSelectedTemplate(); InputStream is = null; try { if (template.isLocal()) { is = new FileInputStream(new File(template.getPath())); } else { URL url = new URL(template.getPath()); is = url.openStream(); } Unzip(is, newProjectHandle, true, monitor); } catch (IOException e) { e.printStackTrace(); } // IProjectDescription desc = newProjectHandle.getDescription(); // desc.setName(projectName); // newProjectHandle.setDescription(desc, monitor); } }; try { // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=219901 // directly execute the operation so that the undo state is // not preserved. Making this undoable resulted in too many // accidental file deletions. op.execute(monitor, WorkspaceUndoUtil .getUIInfoAdapter(getShell())); } catch (ExecutionException e) { throw new InvocationTargetException(e); } } }; // run the new project creation operation try { getContainer().run(true, true, op); } catch (InterruptedException e) { return null; } catch (InvocationTargetException e) { Throwable t = e.getTargetException(); if (t instanceof ExecutionException && t.getCause() instanceof CoreException) { CoreException cause = (CoreException) t.getCause(); StatusAdapter status; if (cause.getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) { status = new StatusAdapter( StatusUtil .newStatus( IStatus.WARNING, NLS .bind( ResourceMessages.NewProject_caseVariantExistsError, newProjectHandle .getName()), cause)); } else { status = new StatusAdapter(StatusUtil.newStatus(cause .getStatus().getSeverity(), ResourceMessages.NewProject_errorMessage, cause)); } status.setProperty(StatusAdapter.TITLE_PROPERTY, ResourceMessages.NewProject_errorMessage); StatusManager.getManager().handle(status, StatusManager.BLOCK); } else { StatusAdapter status = new StatusAdapter(new Status( IStatus.WARNING, IDEWorkbenchPlugin.IDE_WORKBENCH, 0, NLS.bind(ResourceMessages.NewProject_internalError, t .getMessage()), t)); status.setProperty(StatusAdapter.TITLE_PROPERTY, ResourceMessages.NewProject_errorMessage); StatusManager.getManager().handle(status, StatusManager.LOG | StatusManager.BLOCK); } return null; } newProject = newProjectHandle; return newProject; } /** * ��ѹ������Ӧ��ѹ���ļ�����ָ����λ�á� * @param is * @param target * @param filePattern �ļ�����·����ƥ��������ʽ������null����ȫ����ѹ * @param overwrite �����Ѿ����ڵ��ļ��Ƿ񸲸� * @param pm */ public static void Unzip(InputStream is, IContainer target, boolean overwrite, IProgressMonitor monitor) throws CoreException, IOException{ ZipArchiveInputStream zip = new ZipArchiveInputStream(is, null, true); ArchiveEntry entry; monitor = Util.monitorFor(monitor); monitor.beginTask("", IProgressMonitor.UNKNOWN); entry = zip.getNextEntry(); while (entry != null) { boolean canProcess = true; if (StringUtils.equals(entry.getName(), "template.xml") || StringUtils.endsWith(entry.getName(), ".svn")) { canProcess = false; } if (canProcess) { if (entry.isDirectory()) { IFolder folder = target.getFolder(new Path(entry.getName())); ResourcesUtil.safelyCreateFolder(folder); } else { ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = zip.read(buffer)) > 0) { bos.write(buffer, 0, len); } // �滻ģ���е���Ŀ��Ϊ�û���������� if (StringUtils.equals(entry.getName(), ".project")) { InputStream inputStream = new ByteArrayInputStream(bos.toByteArray()); SAXReader reader = new SAXReader(); try { Document document = reader.read(inputStream); Element root = document.getRootElement(); Element element = root.element("name"); element.setText(target.getName()); OutputFormat format = OutputFormat.createPrettyPrint(); format.setIndent(true); format.setEncoding("utf-8"); bos.close(); bos = new ByteArrayOutputStream(); XMLWriter writer = new XMLWriter(bos, format); writer.write(document); } catch (Exception exception) { logger.error(exception); } } bos.close(); IFile file = target.getFile(new Path(entry.getName())); ResourcesUtil.safelyCreateFile(file, new ByteArrayInputStream(bos.toByteArray()), overwrite, null); } } monitor.worked(1); entry = zip.getNextEntry(); } zip.close(); monitor.done(); } /** * Returns the newly created project. * * @return the created project, or <code>null</code> if project not * created */ public IProject getNewProject() { return newProject; } /* * (non-Javadoc) Method declared on IWorkbenchWizard. */ public void init(IWorkbench workbench, IStructuredSelection currentSelection) { super.init(workbench, currentSelection); setNeedsProgressMonitor(true); setWindowTitle(ResourceMessages.NewProject_windowTitle); } /* * (non-Javadoc) Method declared on BasicNewResourceWizard. */ protected void initializeDefaultPageImageDescriptor() { ImageDescriptor desc = IDEWorkbenchPlugin .getIDEImageDescriptor("wizban/newprj_wiz.png");//$NON-NLS-1$ setDefaultPageImageDescriptor(desc); } /* * (non-Javadoc) Opens a new window with a particular perspective and input. */ private static void openInNewWindow(IPerspectiveDescriptor desc) { // Open the page. try { PlatformUI.getWorkbench().openWorkbenchWindow(desc.getId(), ResourcesPlugin.getWorkspace().getRoot()); } catch (WorkbenchException e) { IWorkbenchWindow window = PlatformUI.getWorkbench() .getActiveWorkbenchWindow(); if (window != null) { ErrorDialog.openError(window.getShell(), WINDOW_PROBLEMS_TITLE, e.getMessage(), e.getStatus()); } } } /* * (non-Javadoc) Method declared on IWizard. */ public boolean performFinish() { createNewProject(); if (newProject == null) { return false; } IWorkingSet[] workingSets = mainPage.getSelectedWorkingSets(); getWorkbench().getWorkingSetManager().addToWorkingSets(newProject, workingSets); updatePerspective(); selectAndReveal(newProject); return true; } /* * (non-Javadoc) Replaces the current perspective with the new one. */ private static void replaceCurrentPerspective(IPerspectiveDescriptor persp) { // Get the active page. IWorkbenchWindow window = PlatformUI.getWorkbench() .getActiveWorkbenchWindow(); if (window == null) { return; } IWorkbenchPage page = window.getActivePage(); if (page == null) { return; } // Set the perspective. page.setPerspective(persp); } /** * Stores the configuration element for the wizard. The config element will * be used in <code>performFinish</code> to set the result perspective. */ public void setInitializationData(IConfigurationElement cfig, String propertyName, Object data) { configElement = cfig; } /** * Updates the perspective for the active page within the window. */ protected void updatePerspective() { updatePerspective(configElement); } /** * Updates the perspective based on the current settings in the * Workbench/Perspectives preference page. * * Use the setting for the new perspective opening if we are set to open in * a new perspective. * <p> * A new project wizard class will need to implement the * <code>IExecutableExtension</code> interface so as to gain access to the * wizard's <code>IConfigurationElement</code>. That is the configuration * element to pass into this method. * </p> * * @param configElement - * the element we are updating with * * @see IPreferenceConstants#OPM_NEW_WINDOW * @see IPreferenceConstants#OPM_ACTIVE_PAGE * @see IWorkbenchPreferenceConstants#NO_NEW_PERSPECTIVE */ public static void updatePerspective(IConfigurationElement configElement) { // Do not change perspective if the configuration element is // not specified. if (configElement == null) { return; } // Retrieve the new project open perspective preference setting String perspSetting = PrefUtil.getAPIPreferenceStore().getString( IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE); String promptSetting = IDEWorkbenchPlugin.getDefault() .getPreferenceStore().getString( IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE); // Return if do not switch perspective setting and are not prompting if (!(promptSetting.equals(MessageDialogWithToggle.PROMPT)) && perspSetting .equals(IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE)) { return; } // Read the requested perspective id to be opened. String finalPerspId = configElement.getAttribute(FINAL_PERSPECTIVE); if (finalPerspId == null) { return; } // Map perspective id to descriptor. IPerspectiveRegistry reg = PlatformUI.getWorkbench() .getPerspectiveRegistry(); // leave this code in - the perspective of a given project may map to // activities other than those that the wizard itself maps to. IPerspectiveDescriptor finalPersp = reg .findPerspectiveWithId(finalPerspId); if (finalPersp != null && finalPersp instanceof IPluginContribution) { IPluginContribution contribution = (IPluginContribution) finalPersp; if (contribution.getPluginId() != null) { IWorkbenchActivitySupport workbenchActivitySupport = PlatformUI .getWorkbench().getActivitySupport(); IActivityManager activityManager = workbenchActivitySupport .getActivityManager(); IIdentifier identifier = activityManager .getIdentifier(WorkbenchActivityHelper .createUnifiedId(contribution)); Set idActivities = identifier.getActivityIds(); if (!idActivities.isEmpty()) { Set enabledIds = new HashSet(activityManager .getEnabledActivityIds()); if (enabledIds.addAll(idActivities)) { workbenchActivitySupport .setEnabledActivityIds(enabledIds); } } } } else { IDEWorkbenchPlugin.log("Unable to find persective " //$NON-NLS-1$ + finalPerspId + " in BasicNewProjectResourceWizard.updatePerspective"); //$NON-NLS-1$ return; } // gather the preferred perspectives // always consider the final perspective (and those derived from it) // to be preferred ArrayList preferredPerspIds = new ArrayList(); addPerspectiveAndDescendants(preferredPerspIds, finalPerspId); String preferred = configElement.getAttribute(PREFERRED_PERSPECTIVES); if (preferred != null) { StringTokenizer tok = new StringTokenizer(preferred, " \t\n\r\f,"); //$NON-NLS-1$ while (tok.hasMoreTokens()) { addPerspectiveAndDescendants(preferredPerspIds, tok.nextToken()); } } IWorkbenchWindow window = PlatformUI.getWorkbench() .getActiveWorkbenchWindow(); if (window != null) { IWorkbenchPage page = window.getActivePage(); if (page != null) { IPerspectiveDescriptor currentPersp = page.getPerspective(); // don't switch if the current perspective is a preferred // perspective if (currentPersp != null && preferredPerspIds.contains(currentPersp.getId())) { return; } } // prompt the user to switch if (!confirmPerspectiveSwitch(window, finalPersp)) { return; } } int workbenchPerspectiveSetting = WorkbenchPlugin.getDefault() .getPreferenceStore().getInt( IPreferenceConstants.OPEN_PERSP_MODE); // open perspective in new window setting if (workbenchPerspectiveSetting == IPreferenceConstants.OPM_NEW_WINDOW) { openInNewWindow(finalPersp); return; } // replace active perspective setting otherwise replaceCurrentPerspective(finalPersp); } /** * Adds to the list all perspective IDs in the Workbench who's original ID * matches the given ID. * * @param perspectiveIds * the list of perspective IDs to supplement. * @param id * the id to query. * @since 3.0 */ private static void addPerspectiveAndDescendants(List perspectiveIds, String id) { IPerspectiveRegistry registry = PlatformUI.getWorkbench() .getPerspectiveRegistry(); IPerspectiveDescriptor[] perspectives = registry.getPerspectives(); for (int i = 0; i < perspectives.length; i++) { // @issue illegal ref to workbench internal class; // consider adding getOriginalId() as API on IPerspectiveDescriptor PerspectiveDescriptor descriptor = ((PerspectiveDescriptor) perspectives[i]); if (descriptor.getOriginalId().equals(id)) { perspectiveIds.add(descriptor.getId()); } } } public boolean canFinish() { if (!(getContainer().getCurrentPage() instanceof TemplateSelectWizardPage)) return false; return super.canFinish(); } /** * Prompts the user for whether to switch perspectives. * * @param window * The workbench window in which to switch perspectives; must not * be <code>null</code> * @param finalPersp * The perspective to switch to; must not be <code>null</code>. * * @return <code>true</code> if it's OK to switch, <code>false</code> * otherwise */ private static boolean confirmPerspectiveSwitch(IWorkbenchWindow window, IPerspectiveDescriptor finalPersp) { IPreferenceStore store = IDEWorkbenchPlugin.getDefault() .getPreferenceStore(); String pspm = store .getString(IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE); if (!IDEInternalPreferences.PSPM_PROMPT.equals(pspm)) { // Return whether or not we should always switch return IDEInternalPreferences.PSPM_ALWAYS.equals(pspm); } String desc = finalPersp.getDescription(); String message; if (desc == null || desc.length() == 0) message = NLS.bind(ResourceMessages.NewProject_perspSwitchMessage, finalPersp.getLabel()); else message = NLS.bind( ResourceMessages.NewProject_perspSwitchMessageWithDesc, new String[] { finalPersp.getLabel(), desc }); MessageDialogWithToggle dialog = MessageDialogWithToggle .openYesNoQuestion(window.getShell(), ResourceMessages.NewProject_perspSwitchTitle, message, null /* use the default message for the toggle */, false /* toggle is initially unchecked */, store, IDEInternalPreferences.PROJECT_SWITCH_PERSP_MODE); int result = dialog.getReturnCode(); // If we are not going to prompt anymore propogate the choice. if (dialog.getToggleState()) { String preferenceValue; if (result == IDialogConstants.YES_ID) { // Doesn't matter if it is replace or new window // as we are going to use the open perspective setting preferenceValue = IWorkbenchPreferenceConstants.OPEN_PERSPECTIVE_REPLACE; } else { preferenceValue = IWorkbenchPreferenceConstants.NO_NEW_PERSPECTIVE; } // update PROJECT_OPEN_NEW_PERSPECTIVE to correspond PrefUtil.getAPIPreferenceStore().setValue( IDE.Preferences.PROJECT_OPEN_NEW_PERSPECTIVE, preferenceValue); } return result == IDialogConstants.YES_ID; } }