/******************************************************************************* * 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.util.*; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IPath; import org.eclipse.jface.text.source.ISourceViewer; import org.jboss.tools.common.model.*; import org.jboss.tools.common.model.filesystems.XFileObject; import org.jboss.tools.common.model.util.EclipseResourceUtil; import org.jboss.tools.common.meta.*; import org.jboss.tools.jsf.JSFModelPlugin; import org.jboss.tools.jsf.model.pv.JSFProjectBean; import org.jboss.tools.jsf.project.JSFNature; import org.jboss.tools.jsf.web.JSFWebProject; import org.jboss.tools.jsf.web.pattern.JSFUrlPattern; import org.jboss.tools.jst.web.project.WebProject; import org.jboss.tools.jst.web.tld.TaglibData; import org.jboss.tools.jst.web.tld.VpeTaglibManager; import org.jboss.tools.jst.web.tld.VpeTaglibManagerProvider; import org.jboss.tools.jst.web.tld.model.TLDUtil; public class JSPAdopt implements XAdoptManager { public boolean isAdoptable(XModelObject target, XModelObject object) { if(!isAcceptableTarget(target)) return false; return isAdoptableProperty(object) || isAdoptablePropertyReference(object) || isAdoptablePage(object) || isAdoptableFile(object) || isAdoptableMapEntry(object); } public void adopt(XModelObject target, XModelObject object, java.util.Properties p) throws XModelException { if(isAdoptableProperty(object)) adoptProperty(target, object, p); else if(isAdoptablePropertyReference(object)) adoptPropertyReference(target, object, p); else if(isAdoptablePage(object)) adoptPage(target, object, p); else if(isAdoptableFile(object)) adoptFile(target, object, p); else if(isAdoptableMapEntry(object)) adoptMapEntry(target, object, p); } static String PAGE_TARGET = ".FileJSP.FileHTML.FileXHTML.FacesConfig."; //$NON-NLS-1$ static String PAGE_ENTITY = ".FileJSP.FileXHTML."; //$NON-NLS-1$ private boolean isAcceptableTarget(XModelObject target) { String entity = "." + target.getModelEntity().getName() + "."; //$NON-NLS-1$ //$NON-NLS-2$ return PAGE_TARGET.indexOf(entity) >= 0; } protected boolean isAdoptableProperty(XModelObject object) { return object.getModelEntity().getName().startsWith("JSFManagedProperty"); //$NON-NLS-1$ } public void adoptProperty(XModelObject target, XModelObject object, Properties p) { if(p == null) return; int c = getPos(p); if(c < 0) return; String bean = object.getParent().getAttributeValue("managed-bean-name"); //$NON-NLS-1$ String name = object.getAttributeValue("property-name"); //$NON-NLS-1$ String start = "#{" + bean + "." + name + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ p.setProperty("start text", start); //$NON-NLS-1$ } protected boolean isAdoptablePage(XModelObject object) { String entity = "." + object.getModelEntity().getName() + "."; //$NON-NLS-1$ //$NON-NLS-2$ if(PAGE_ENTITY.indexOf(entity) < 0 || !EclipseResourceUtil.hasNature(object.getModel(), JSFNature.NATURE_ID)) return false; String path = WebProject.getInstance(object.getModel()).getPathInWebRoot(object); return path != null; } public void adoptPage(XModelObject target, XModelObject object, Properties p) { if(p == null) return; String res = WebProject.getInstance(object.getModel()).getPathInWebRoot(object); if(res == null) return; if(applyPattern(p)) { JSFUrlPattern pattern = JSFWebProject.getInstance(object.getModel()).getPatternLoader().getUrlPattern(); res = pattern.getJSFUrl(res); } int pos = getPos(p); if(res.startsWith("/") && pos >= 0 && isInsideResponseRedirect(p.getProperty("text"), pos)) { //$NON-NLS-1$ //$NON-NLS-2$ res = res.substring(1); } p.setProperty("start text", res); //$NON-NLS-1$ p.setProperty("end text", ""); //$NON-NLS-1$ //$NON-NLS-2$ } static String NO_JSF_URL = "+include+jsp:include+jsp:directive.include+ui:include+ui:composition+ui:decorate+s:decorate+"; //$NON-NLS-1$ static Map<String, String> PREFIXES = new HashMap<String, String>(); { PREFIXES.put("http://jboss.com/products/seam/taglib", "s"); //$NON-NLS-1$ //$NON-NLS-2$ PREFIXES.put("http://java.sun.com/jsf/facelets", "ui"); //$NON-NLS-1$ //$NON-NLS-2$ } boolean applyPattern(Properties p) { if(p == null) return true; String tag = p.getProperty("context:tagName"); //$NON-NLS-1$ if(tag == null) return true; int q = tag.indexOf(':'); if(q >= 0) { String dp = tag.substring(0, q); ISourceViewer sv = (ISourceViewer)p.get("viewer"); //$NON-NLS-1$ String uri = getURI(sv, dp); if(uri != null) { String dp1 = PREFIXES.get(uri); if(dp1 != null && !dp1.equals(dp)) { tag = dp1 + tag.substring(q); } } } if(NO_JSF_URL.indexOf("+" + tag + "+") >= 0) return false; //$NON-NLS-1$ //$NON-NLS-2$ return true; } private static String getURI(ISourceViewer viewer, String prefix) { VpeTaglibManager tldManager = null; if((tldManager == null) && (viewer instanceof VpeTaglibManagerProvider)) { tldManager = ((VpeTaglibManagerProvider)viewer).getTaglibManager(); if(tldManager != null) { List list = tldManager.getTagLibs(); for (int i = 0; i < list.size(); i++) { TaglibData data = (TaglibData)list.get(i); if(prefix.equals(data.getPrefix())) { return data.getUri(); } } } } return null; } protected boolean isAdoptableFile(XModelObject object) { if(XFileObject.FILE != object.getFileType()) return false; if(TLDUtil.isTaglib(object)) return false; IResource c = (IResource)object.getAdapter(IResource.class); if(c == null) return false; String webroot = WebProject.getInstance(object.getModel()).getWebRootLocation(); if(webroot == null) return false; IPath path = c.getLocation(); // if this happens it means that something is wrong // with reference to IResource in object or its parent // that may need attention. if(path == null || path.toString() == null) return false; String f = path.toString().replace('\\', '/').toLowerCase(); webroot = webroot.replace('\\', '/').toLowerCase(); return f.startsWith(webroot); } public void adoptFile(XModelObject target, XModelObject object, Properties p) { if(p == null) return; String webroot = WebProject.getInstance(object.getModel()).getWebRootLocation(); IResource c = (IResource)object.getAdapter(IResource.class); String f = c.getLocation().toString().replace('\\', '/'); String res = f.substring(webroot.length()); p.setProperty("start text", res); //$NON-NLS-1$ p.setProperty("end text", ""); //$NON-NLS-1$ //$NON-NLS-2$ } protected boolean isAdoptablePropertyReference(XModelObject object) { String entity = "." + object.getModelEntity().getName() + "."; //$NON-NLS-1$ //$NON-NLS-2$ return ".JSFProjectBeanProperty.JSFProjectBeanMethod.".indexOf(entity) >= 0; //$NON-NLS-1$ } public void adoptPropertyReference(XModelObject target, XModelObject object, Properties p) { if(p == null) return; int c = getPos(p); if(c < 0) return; String s = object.getAttributeValue("name"); //$NON-NLS-1$ XModelObject o = object; while(o != null && isAdoptablePropertyReference(o)) { o = o.getParent(); if(o != null) { String part = o.getAttributeValue("name"); //$NON-NLS-1$ if(o instanceof JSFProjectBean) { XModelObject[] list = ((JSFProjectBean)o).getBeanList(); if(list.length > 1) { part = SelectBeanSupport.run((JSFProjectBean)o); if(part == null) return; } } s = part + "." + s; //$NON-NLS-1$ } } String start = "#{" + s + "}"; //$NON-NLS-1$ //$NON-NLS-2$ p.setProperty("start text", start); //$NON-NLS-1$ } int getPos(Properties p) { int c = -1; if(p == null) return -1; String s = p.getProperty("pos"); //$NON-NLS-1$ if(s == null || s.trim().length() == 0) return c; try { c = Integer.parseInt(s.trim()); } catch (NumberFormatException e) { JSFModelPlugin.getPluginLog().logError(e); } return c; } public boolean isAdoptableMapEntry(XModelObject object) { return "JSFMapEntry".equals(object.getModelEntity().getName()); //$NON-NLS-1$ } public void adoptMapEntry(XModelObject target, XModelObject object, Properties p) { String key = object.getAttributeValue("key"); //$NON-NLS-1$ XModelObject g = object.getParent().getParent(); String entity = g.getModelEntity().getName(); String start = null; if("JSFManagedBean".equals(entity) || "JSFManagedBean20".equals(entity)) { //$NON-NLS-1$ String bean = g.getAttributeValue("managed-bean-name"); //$NON-NLS-1$ start = "#{" + bean + "." + key + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } else if("JSFManagedProperty".equals(entity)) { //$NON-NLS-1$ XModelObject h = g.getParent(); String bean = h.getAttributeValue("managed-bean-name"); //$NON-NLS-1$ String property = g.getAttributeValue("property-name"); //$NON-NLS-1$ start = "#{" + bean + "." + property + "." + key + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } if(start != null) { p.setProperty("start text", start); //$NON-NLS-1$ } } static boolean isInsideResponseRedirect(String text, int off) { if(off < 0) return false; String START = "response.sendRedirect(\""; //$NON-NLS-1$ String END = "\")"; //$NON-NLS-1$ int i = 0; while(i < text.length() && i < off) { int i1 = text.indexOf(START, i); if(i1 < 0 || i1 + START.length() > off) return false; int i2 = text.indexOf(END, i1 + START.length()); if(i2 < 0 || i2 >= off) return true; i = i2 + END.length(); } return false; } }