/******************************************************************************* * Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is 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: * Exadel, Inc. and Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.jsf.model.handlers; import java.io.File; import java.io.IOException; import java.util.Map; import java.util.Properties; import java.util.TreeMap; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.templates.DocumentTemplateContext; import org.eclipse.jface.text.templates.Template; import org.eclipse.jface.text.templates.TemplateBuffer; import org.eclipse.jface.text.templates.TemplateContext; import org.eclipse.jface.text.templates.TemplateContextType; import org.eclipse.jface.text.templates.TemplateException; import org.eclipse.jface.text.templates.persistence.TemplateStore; import org.eclipse.jst.jsp.ui.internal.JSPUIPlugin; import org.eclipse.jst.jsp.ui.internal.templates.TemplateContextTypeIdsJSP; import org.eclipse.osgi.util.NLS; import org.jboss.tools.common.meta.action.impl.DefaultWizardDataValidator; import org.jboss.tools.common.meta.action.impl.SpecialWizardSupport; import org.jboss.tools.common.meta.action.impl.WizardDataValidator; import org.jboss.tools.common.meta.action.impl.handlers.DefaultCreateHandler; import org.jboss.tools.common.model.ServiceDialog; import org.jboss.tools.common.model.XModelException; import org.jboss.tools.common.model.XModelObject; import org.jboss.tools.common.model.filesystems.impl.FileSystemImpl; import org.jboss.tools.common.model.impl.XModelObjectImpl; import org.jboss.tools.common.model.options.PreferenceModelUtilities; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.model.util.FindObjectHelper; import org.jboss.tools.common.util.FileUtil; import org.jboss.tools.jsf.JSFModelPlugin; import org.jboss.tools.jsf.JSFPreference; import org.jboss.tools.jsf.model.JSFConstants; import org.jboss.tools.jsf.model.JSFNavigationModel; import org.jboss.tools.jsf.model.ReferenceGroupImpl; import org.jboss.tools.jsf.model.helpers.JSFProcessHelper; import org.jboss.tools.jsf.model.impl.NavigationRuleObjectImpl; import org.jboss.tools.jsf.messages.JSFUIMessages; public class AddViewSupport extends SpecialWizardSupport implements JSFConstants { public static String JSF_ADD_VIEW_PATH = JSFPreference.JSF_ADD_VIEW_PATH; // JSFTemplate templates = new JSFTemplate(); static String LAST_CREATE_FILE_PREFERENCE = "org.jboss.tools.jsf.lastCreateFileValue"; //$NON-NLS-1$ XModelObject sample; Map<String, Template> templates = null; public void reset() { sample = (XModelObject)getProperties().get("sample"); //$NON-NLS-1$ if(sample != null) { setAttributeValue(0, ATT_FROM_VIEW_ID, sample.getAttributeValue(ATT_PATH)); } loadTemplates(); String[] s = templates.keySet().toArray(new String[0]); setValueList(0, "template", s); //$NON-NLS-1$ //take from preferences setAttributeValue(0, "template", getDefaultTemplate(s)); //$NON-NLS-1$ String last = JSFModelPlugin.getDefault().getPluginPreferences().getString(LAST_CREATE_FILE_PREFERENCE); if(last == null || last.length() == 0) { last = "true"; //$NON-NLS-1$ } else if(!"true".equals(last)) { //$NON-NLS-1$ last = "false"; //$NON-NLS-1$ } setAttributeValue(0, "create file", last); //$NON-NLS-1$ } TemplateStore getTemplateStore() { return JSPUIPlugin.getInstance().getTemplateStore(); } String getTemplateString(String templateName) { if(templateName == null) return null; String templateString = null; Template template = templates.get(templateName); if (template != null) { TemplateContextType contextType =JSPUIPlugin.getInstance().getTemplateContextRegistry().getContextType(TemplateContextTypeIdsJSP.NEW); IDocument document = new Document(); TemplateContext context = new DocumentTemplateContext(contextType, document, 0, 0); try { TemplateBuffer buffer = context.evaluate(template); templateString = buffer.getString(); } catch (BadLocationException e) { JSFModelPlugin.getDefault().logWarning("Could not create template for new html", e); //$NON-NLS-1$ } catch (TemplateException e) { JSFModelPlugin.getDefault().logWarning("Could not create template for new html", e); //$NON-NLS-1$ } } return templateString; } void loadTemplates() { templates = new TreeMap<String, Template>(); Template[] ts = getTemplateStore().getTemplates(TemplateContextTypeIdsJSP.NEW); for (Template t: ts) { templates.put(t.getName(), t); } } static XModelObject getPreferenceObject() { return PreferenceModelUtilities.getPreferenceModel().getByPath(JSF_ADD_VIEW_PATH); } public String getDefaultTemplate(String[] list) { if(list.length == 0) return ""; //$NON-NLS-1$ XModelObject addView = getPreferenceObject(); String v = (addView == null) ? "" : addView.getAttributeValue("Page Template"); //$NON-NLS-1$ //$NON-NLS-2$ if(v != null) for (int i = 0; i < list.length; i++) if(v.equals(list[i])) return list[i]; return list[0]; } public String getExtension(String template) { if(template != null) { int i = template.trim().lastIndexOf('.'); if(i > 0) { return template.trim().substring(i); } } return getExtension(); } public static String getExtension() { XModelObject addView = getPreferenceObject(); String v = (addView == null) ? "" : addView.getAttributeValue("Extension"); //$NON-NLS-1$ //$NON-NLS-2$ if(v == null || v.length() == 0) return ".jsp"; //$NON-NLS-1$ if(!v.startsWith(".")) v = "." + v; //$NON-NLS-1$ //$NON-NLS-2$ return v; } public void action(String name) throws XModelException { if(FINISH.equals(name)) { execute(); setFinished(true); } else if(CANCEL.equals(name)) { setFinished(true); } } public String[] getActionNames(int stepId) { return new String[]{FINISH, CANCEL, HELP}; } protected void execute() throws XModelException { boolean doNotCreateEmptyRule = "yes".equals(JSFPreference.DO_NOT_CREATE_EMPTY_RULE.getValue()); //$NON-NLS-1$ Properties p = extractStepData(0); String path = p.getProperty("from-view-id"); //$NON-NLS-1$ path = revalidatePath(path, getAttributeValue(0, "template")); //$NON-NLS-1$ createFile(path); JSFNavigationModel m = (JSFNavigationModel)getTarget().getParent(); String pp = NavigationRuleObjectImpl.toNavigationRulePathPart(path); boolean isPattern = JSFProcessHelper.isPattern(path); boolean existsR = m.getRuleCount(path) != 0; boolean existsV = findView(path) != null; boolean exists = existsR || existsV; if(exists) { ServiceDialog d = getTarget().getModel().getService(); String message = NLS.bind(JSFUIMessages.THE_VIEW_WITH_PATH_IS_ALREADY_CREATED, path); if(existsR) { message += JSFUIMessages.YOU_WANT_TO_ADD_ADDITIONAL_NAVIGATION_RULE_WITH_SAME_FROM_VIEW_ID; } else if(existsV && isPattern) { message += JSFUIMessages.YOU_WANT_TO_CREATE_AN_ADDITIONAL_VIEW_WITH_THE_SAME_FROM_VIEW_ID; } else { message += JSFUIMessages.YOU_WANT_TO_CREATE_A_NAVIGATION_RULE_FOR_THIS_FROM_VIEW_ID; } int q = d.showDialog(JSFUIMessages.WARNING, message, new String[]{JSFUIMessages.OK, JSFUIMessages.CANCEL}, null, ServiceDialog.WARNING); if(q != 0) return; } /*TRIAL_JSF*/ XModelObject created = null; if(!doNotCreateEmptyRule || (exists && !isPattern) || sample != null) { XModelObject rule = m.addRule(path); addCasesFromSample(rule); m.setModified(true); created = getTarget().getChildByPath(pp); } else { created = getTarget().getModel().createModelObject(JSFConstants.ENT_PROCESS_GROUP, null); String ppi = pp; if(exists && JSFProcessHelper.isPattern(path)) { int index = -1; while(getTarget().getChildByPath(ppi + ":" + index) != null) index--; //$NON-NLS-1$ ppi = ppi + ":" + index; //$NON-NLS-1$ } created.setAttributeValue(JSFConstants.ATT_NAME, ppi); created.setAttributeValue(JSFConstants.ATT_PATH, path); created.setAttributeValue("persistent", "true"); //$NON-NLS-1$ //$NON-NLS-2$ DefaultCreateHandler.addCreatedObject(getTarget(), created, getProperties()); } if(!exists || isPattern) { String shape = getShape(); if(created != null && shape != null) created.setAttributeValue("shape", shape); //$NON-NLS-1$ } if(created != null) { FindObjectHelper.findModelObject(created, FindObjectHelper.IN_EDITOR_ONLY); } } private XModelObject findView(String path) { String pp = NavigationRuleObjectImpl.toNavigationRulePathPart(path); XModelObject o = getTarget().getChildByPath(pp); if(o != null) return o; if(!JSFProcessHelper.isPattern(path)) return null; XModelObject[] cs = getTarget().getChildren(); for (int i = 0; i < cs.length; i++) { String p = cs[i].getPathPart(); if(pp.equals(p) || p.startsWith(pp + ":")) return cs[i]; //$NON-NLS-1$ } return null; } private void addCasesFromSample(XModelObject rule) { if(!(sample instanceof ReferenceGroupImpl)) return; XModelObject[] rs = ((ReferenceGroupImpl)sample).getReferences(); if(rs == null || rs.length == 0) return; for (int i = 0; i < rs.length; i++) { String caseEntity = rule.getModelEntity().getChildren()[0].getName(); XModelObject[] cs = rs[i].getChildren(); for (int j = 0; j < cs.length; j++) { XModelObject c = cs[j].copy(); if(c.getModelEntity().getName().equals(caseEntity)) { ((XModelObjectImpl)c).changeEntity(caseEntity); } rule.addChild(c); } } } private String getShape() { String x = getProperties().getProperty("process.mouse.x"); //$NON-NLS-1$ String y = getProperties().getProperty("process.mouse.y"); //$NON-NLS-1$ return (x == null || y == null) ? null : x + "," + y + ",0,0"; //$NON-NLS-1$ //$NON-NLS-2$ } public static String revalidatePath(String path) { if(path != null) path = path.trim(); if(path == null || path.length() == 0) return path; if(!path.startsWith("/") && !path.startsWith("*")) path = "/" + path; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if(path.indexOf('*') >= 0) return path; if(path.indexOf('.') < 0 && !path.endsWith("/")) { //$NON-NLS-1$ path += getExtension(); } return path; } String revalidatePath(String path, String template) { if(path != null) path = path.trim(); if(path == null || path.length() == 0) return path; if(!path.startsWith("/") && !path.startsWith("*")) path = "/" + path; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ if(path.indexOf('*') >= 0) return path; if(path.indexOf('.') < 0 && !path.endsWith("/")) { //$NON-NLS-1$ path += getExtension(template); } return path; } public boolean canCreateFile(String path) { XModelObject fs = getTarget().getModel().getByPath("FileSystems/WEB-ROOT"); //$NON-NLS-1$ if(fs == null) return false; path = revalidatePath(path, getAttributeValue(0, "template")); //$NON-NLS-1$ if(path == null || path.length() == 0 || path.indexOf('*') >= 0) return false; return isCorrectPath(path) && !fileExists(path); } static String FORBIDDEN_INDICES = "\"\n\t*\\:<>?|"; //$NON-NLS-1$ static boolean isCorrectPath(String path) { if(path == null || path.equals("/") || path.indexOf("//") >= 0) return false; //$NON-NLS-1$ //$NON-NLS-2$ if(path.endsWith("/") || path.indexOf("../") >= 0) return false; //$NON-NLS-1$ //$NON-NLS-2$ if(path.endsWith("..")) return false; //$NON-NLS-1$ if(path.equals("*")) return true; //$NON-NLS-1$ for (int i = 0; i < FORBIDDEN_INDICES.length(); i++) { if(path.indexOf(FORBIDDEN_INDICES.charAt(i)) >= 0) { return false; } } return true; } boolean fileExists(String path) { return getTarget().getModel().getByPath(path) != null; } void createFile(String path) throws XModelException { if(!canCreateFile(path)) return; String lastCreateFileValue = getAttributeValue(0, "create file"); //$NON-NLS-1$ JSFModelPlugin.getDefault().getPluginPreferences().setDefault(LAST_CREATE_FILE_PREFERENCE, lastCreateFileValue); if(!"true".equals(lastCreateFileValue)) return; //$NON-NLS-1$ String template = getAttributeValue(0, "template"); //$NON-NLS-1$ if(template != null) template = template.trim(); String location = ((FileSystemImpl)getTarget().getModel().getByPath("FileSystems/WEB-ROOT")).getAbsoluteLocation(); //$NON-NLS-1$ location += path; File ft = new File(location); String templateString = getTemplateString(template); try { ft.createNewFile(); } catch (IOException e) { } if(templateString != null) { FileUtil.writeFile(ft, templateString); } getTarget().getModel().update(); try { EclipseResourceUtil.getResource(getTarget()).getProject().refreshLocal(IProject.DEPTH_INFINITE, null); } catch (CoreException e) { throw new XModelException(e); } } protected DefaultWizardDataValidator viewValidator = new ViewValidator(); public WizardDataValidator getValidator(int step) { viewValidator.setSupport(this, step); return viewValidator; } class ViewValidator extends DefaultWizardDataValidator { public void validate(Properties data) { super.validate(data); if(message != null) return; String path = revalidatePath(data.getProperty("from-view-id"), data.getProperty("template")); //$NON-NLS-1$ //$NON-NLS-2$ if(!isCorrectPath(path)) { message = JSFUIMessages.ATTRIBUTE_FROM_VIEW_ID_IS_NOT_CORRECT; } if(message != null) return; String template = data.getProperty("template"); //$NON-NLS-1$ if(template != null && isFieldEditorEnabled(0, "template", data)) { //$NON-NLS-1$ if(template.trim().length() == 0) { message = JSFUIMessages.TEMPLATE_IS_NOT_SPECIFIED; return; } String t = getTemplateString(template.trim()); if(t == null) { message = JSFUIMessages.TEMPLATE_DOES_NOT_EXIST; } } if(message != null) return; boolean doNotCreateEmptyRule = "yes".equals(JSFPreference.DO_NOT_CREATE_EMPTY_RULE.getValue()); //$NON-NLS-1$ JSFNavigationModel m = (JSFNavigationModel)getTarget().getParent(); String pp = NavigationRuleObjectImpl.toNavigationRulePathPart(path); boolean exists = m.getRuleCount(path) != 0 || getTarget().getChildByPath(pp) != null; if(doNotCreateEmptyRule && exists && !JSFProcessHelper.isPattern(path)) { message = JSFUIMessages.THE_VIEW_EXISTS; } } } public boolean isFieldEditorEnabled(int stepId, String name, Properties values) { String path = values.getProperty("from-view-id"); //$NON-NLS-1$ boolean c = canCreateFile(path); if(name.equals("create file")) { //$NON-NLS-1$ return c; } boolean g = c && "true".equals(values.getProperty("create file")); //$NON-NLS-1$ //$NON-NLS-2$ if(name.equals("template")) { //$NON-NLS-1$ return g; } return true; } }