/******************************************************************************* * Copyright (c) 2012 VMware, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VMware, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.metadata.wizards; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.mylyn.tasks.ui.TasksUiUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IMemento; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.XMLMemento; import org.eclipse.wst.server.core.IModule; import org.eclipse.wst.server.core.IServer; import org.eclipse.wst.server.core.ServerUtil; import org.eclipse.wst.server.core.model.IURLProvider; import org.springframework.ide.eclipse.metadata.MetadataPlugin; import org.springframework.ide.eclipse.metadata.ui.RequestMappingMethodToClassMap; import org.springframework.ide.eclipse.metadata.ui.RequestMappingView; import org.springframework.ide.eclipse.metadata.ui.RequestMappingViewLabelProvider; import org.springsource.ide.eclipse.commons.core.StatusHandler; /** * @author Leo Dos Santos * @author Christian Dupuis */ public class OpenRequestMappingUrlWizardPage extends WizardPage { private static String PREFIX_VARIABLE_PREFS = "com.springsource.sts.metadata.url.wizard.variables"; //$NON-NLS-1$ private static String KEY_ROOT = "root"; //$NON-NLS-1$ private static String KEY_URL_DATA = "urlData"; //$NON-NLS-1$ private static String KEY_NAME = "name"; //$NON-NLS-1$ private static String KEY_VALUE = "value"; //$NON-NLS-1$ private IPreferenceStore prefStore; private String prefStoreKey; private RequestMappingMethodToClassMap input; private RequestMappingViewLabelProvider labelProvider; private IProject project; private List<Combo> comboList; private Map<String, List<String>> cacheMap; private Combo urlText; protected OpenRequestMappingUrlWizardPage(RequestMappingMethodToClassMap input, RequestMappingViewLabelProvider labelProvider, IProject project) { super(Messages.OpenRequestMappingUrlWizardPage_PAGE_TITLE); setTitle(Messages.OpenRequestMappingUrlWizardPage_HEADER_TITLE); setDescription(Messages.OpenRequestMappingUrlWizardPage_DESCRIPTION); this.input = input; this.labelProvider = labelProvider; this.project = project; prefStore = MetadataPlugin.getDefault().getPreferenceStore(); prefStoreKey = PREFIX_VARIABLE_PREFS.concat(input.getMethodMetadata().getHandleIdentifier()); comboList = new ArrayList<Combo>(); cacheMap = new HashMap<String, List<String>>(); } public void createControl(Composite parent) { Composite container = new Composite(parent, SWT.NONE); container.setLayout(new GridLayout(2, false)); Set<String> urlInput = new HashSet<String>(); IModule[] modules = ServerUtil.getModules(project); if (modules != null) { for (IModule module : modules) { IServer[] servers = ServerUtil.getServersByModule(module, new NullProgressMonitor()); for (IServer server : servers) { IURLProvider provider = (IURLProvider) server.loadAdapter(IURLProvider.class, new NullProgressMonitor()); if (provider != null) { URL url = provider.getModuleRootURL(module); if (url != null) { urlInput.add(url.toString()); } } } } } Label urlLabel = new Label(container, SWT.NONE); urlLabel.setText(Messages.OpenRequestMappingUrlWizardPage_LABEL_URL_PREFIX); urlText = new Combo(container, SWT.DROP_DOWN); urlText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); urlText.addModifyListener(new TextModifyListener()); if (urlInput.size() > 0) { urlText.setItems(urlInput.toArray(new String[urlInput.size()])); urlText.select(0); } loadPreferenceCache(); createVariableControls(container); setControl(container); setPageComplete(validatePage()); } private void createVariableControls(Composite parent) { String url = labelProvider.getColumnText(input, RequestMappingView.COLUMN_URL); Pattern pattern = Pattern.compile("\\{\\w*\\}"); //$NON-NLS-1$ Matcher matcher = pattern.matcher(url); while (matcher.find()) { String textLabel = matcher.group(); Label label = new Label(parent, SWT.NONE); label.setText(textLabel + ": "); //$NON-NLS-1$ Combo combo = new Combo(parent, SWT.DROP_DOWN); combo.setData(KEY_URL_DATA, textLabel); combo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); comboList.add(combo); if (cacheMap.containsKey(textLabel)) { List<String> strings = cacheMap.get(textLabel); combo.setItems(strings.toArray(new String[strings.size()])); combo.setText(combo.getItem(0)); } combo.addModifyListener(new TextModifyListener()); } } private void loadPreferenceCache() { String cache = prefStore.getString(prefStoreKey); if (cache != null && cache.length() > 0) { try { IMemento memento = XMLMemento.createReadRoot(new StringReader(cache)); IMemento[] children = memento.getChildren(KEY_URL_DATA); for (IMemento child : children) { String name = child.getString(KEY_NAME); String value = child.getString(KEY_VALUE); if (name != null && value != null) { List<String> subList = cacheMap.get(name); if (subList == null) { subList = new LinkedList<String>(); } subList.add(value); cacheMap.put(name, subList); } } } catch (WorkbenchException e) { StatusHandler.log(new Status(IStatus.ERROR, MetadataPlugin.PLUGIN_ID, Messages.OpenRequestMappingUrlWizardPage_ERROR_LOADING_CACHE, e)); } } } private void savePreferenceCache() { String mementoString = null; XMLMemento rootMemento = XMLMemento.createWriteRoot(KEY_ROOT); for (Combo combo : comboList) { String textLabel = (String) combo.getData(KEY_URL_DATA); String value = combo.getText(); List<String> subList = cacheMap.get(textLabel); if (subList == null) { subList = new LinkedList<String>(); } subList.remove(value); subList.add(0, value); cacheMap.put(textLabel, subList); for (int i = 0; i < subList.size(); i++) { if (i >= 10) { break; } IMemento child = rootMemento.createChild(KEY_URL_DATA); child.putString(KEY_NAME, textLabel); child.putString(KEY_VALUE, subList.get(i)); } } try { StringWriter writer = new StringWriter(); rootMemento.save(writer); mementoString = writer.getBuffer().toString(); prefStore.setValue(prefStoreKey, mementoString); } catch (IOException e) { StatusHandler.log(new Status(IStatus.ERROR, MetadataPlugin.PLUGIN_ID, Messages.OpenRequestMappingUrlWizardPage_ERROR_SAVING_CACHE, e)); } } private String getConstructedUrl() { String url = ""; //$NON-NLS-1$ if (urlText != null) { url = urlText.getText(); if (url.endsWith("/")) { //$NON-NLS-1$ url = url.substring(0, url.length()-1); } } url = url.concat(labelProvider.getColumnText(input, RequestMappingView.COLUMN_URL)); for (Combo combo : comboList) { String textLabel = (String) combo.getData(KEY_URL_DATA); url = url.replace(textLabel, combo.getText()); } return url; } protected void performPageFinish() { savePreferenceCache(); TasksUiUtil.openUrl(getConstructedUrl()); } private boolean validatePage() { if (!comboList.isEmpty()) { for (Combo combo : comboList) { if (combo.getText() == null || combo.getText().length() <= 0) { return false; } } } return (urlText.getText() != null && urlText.getText().length() > 0); } private class TextModifyListener implements ModifyListener { public void modifyText(ModifyEvent e) { String errorMessage = null; boolean valid = validatePage(); if (!valid) { errorMessage = "'" + getConstructedUrl() //$NON-NLS-1$ + Messages.OpenRequestMappingUrlWizardPage_WARNING_URL_CONSTRUCTION; } setErrorMessage(errorMessage); setPageComplete(valid); } } }