/*******************************************************************************
* 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.ui.adopt;
import java.util.*;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.source.SourceViewer;
import org.jboss.tools.common.meta.XAdoptManager;
import org.jboss.tools.common.model.XModelException;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.util.XModelObjectLoaderUtil;
import org.jboss.tools.jsf.project.JSFNature;
import org.jboss.tools.jsf.ui.JsfUiPlugin;
import org.jboss.tools.jst.web.project.list.WebPromptingProvider;
public class JSPAdopt implements XAdoptManager {
public boolean isAdoptable(XModelObject target, XModelObject object) {
return (isAdoptableProperty(object) ||
(isAdoptableNature(target) && isAdoptableBundle(object)));
}
protected boolean isAdoptableProperty(XModelObject object) {
String entity = object.getModelEntity().getName();
return "Property".equals(entity); //$NON-NLS-1$
}
protected boolean isAdoptableNature(XModelObject target) {
if(target == null) return false;
String nature = (String)target.getModel().getProperties().get("nature"); //$NON-NLS-1$
return JSF_NATURE_STRING.equalsIgnoreCase(nature);
}
protected boolean isAdoptableBundle(XModelObject object) {
return "FilePROPERTIES".equals(object.getModelEntity().getName()); //$NON-NLS-1$
}
public void adopt(XModelObject target, XModelObject object, Properties p) throws XModelException {
if(isAdoptableProperty(object)) adoptProperty(target, object, p);
if(isAdoptableBundle(object)) adoptBundle(target, object, p);
}
public void adoptProperty(XModelObject target, XModelObject object, Properties p) {
String name = object.getAttributeValue("name"); //$NON-NLS-1$
String bundle = getBundle(object.getParent());
int pos = -1;
try {
String s = p == null ? null : p.getProperty("pos"); //$NON-NLS-1$
if(s != null && s.length() > 0) pos = Integer.parseInt(s);
} catch (NumberFormatException e) {
JsfUiPlugin.getPluginLog().logError(e);
}
SourceViewer viewer = (SourceViewer)p.get("viewer"); //$NON-NLS-1$
if(viewer == null) {
JsfUiPlugin.getPluginLog().logError("Viewer is null", new NullPointerException("Viewer is null")); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
if(viewer.getDocument() == null) {
return;
}
JSPTokenizer tokenizer = new JSPTokenizer();
Token root = tokenizer.parse(viewer.getDocument());
Token t = root.firstChild;
while(t != null) {
t = t.nextSibling;
}
int contextIndex = getContextIndex(tokenizer, pos);
if(pos < 0) return;
String jsfCorePrefix = JSPAdoptHelper.getPrefixForURI(root, JSF_CORE_TAGLIB_URI, JSF_CORE_TAGLIB_PREFIX_DEFAULT);
String jsfHtmlPrefix = JSPAdoptHelper.getPrefixForURI(root, JSF_HTML_TAGLIB_URI, JSF_HTML_TAGLIB_PREFIX_DEFAULT);
String prefix = "???"; //$NON-NLS-1$
String varValue = JSPAdoptHelper.getLoadedBundleVar(root, jsfCorePrefix, bundle);
if (varValue != null && varValue.length() > 0) prefix = varValue;
if(prefix.equals("???")) { //$NON-NLS-1$
WebPromptingProvider fProvider = WebPromptingProvider.getInstance();
List<Object> l = fProvider.getList(target.getModel(), WebPromptingProvider.JSF_REGISTERED_BUNDLES, null, null);
int map_index = 1;
Map map = l.size() <= map_index ? null : (Map)l.get(map_index);
if(map != null && map.containsKey(bundle)) prefix = map.get(bundle).toString();
}
tokenizer.isInTagAttributeValue(pos);
if(prefix.equals("???")) { //$NON-NLS-1$
int bp = JSPAdoptHelper.getPositionForBundle(root, jsfCorePrefix);
if(bp < 0) return;
prefix = JSPAdoptHelper.getNameForNewBundle(root, jsfCorePrefix);
String loadBundle = "\n" + createLoadBundleTag(jsfCorePrefix, bundle, prefix); //$NON-NLS-1$
try {
viewer.getDocument().replace(bp, 0, loadBundle);
if(pos >= bp) pos += loadBundle.length();
} catch (BadLocationException e) {
JsfUiPlugin.getPluginLog().logError(e);
}
}
String start = getPropertyReference(prefix, name);
if (contextIndex == 1) {
start = "<" + jsfHtmlPrefix + ":outputText value=\"" + start + "\"/>"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
try {
viewer.getDocument().replace(pos, 0, start);
viewer.setSelectedRange(pos, 0);
viewer.getTextWidget().setFocus();
} catch (BadLocationException e) {
JsfUiPlugin.getPluginLog().logError(e);
}
p.remove("start text"); //$NON-NLS-1$
}
private String getPropertyReference(String prefix, String name) {
return (!isJavaName(name)) ? "#{" + prefix + "['" + name + "']}" : "#{" + prefix + "." + name + "}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
}
private boolean isJavaName(String name) {
if(name.length() == 0) return true;
char ch = name.charAt(0);
if(!Character.isJavaIdentifierStart(ch)) return false;
for (int i = 1; i < name.length(); i++) {
ch = name.charAt(i);
if(!Character.isJavaIdentifierPart(ch)) return false;
}
return true;
}
private int getContextIndex(JSPTokenizer tokenizer, int pos) {
if(tokenizer.root == null) return -1;
if (tokenizer.isInTagAttributeValue(pos)) return 0;
Token e = tokenizer.getTokenAt(pos);
if(e == null) return -1;
if (e.kind == JSPTokenizer.TEXT || (pos == e.off)) {
return 1;
}
return -1;
}
private static final String JSF_NATURE_STRING = JSFNature.NATURE_ID;
private String createLoadBundleTag(String jsfCorePrefix, String bundlePath, String var) {
return "<" + jsfCorePrefix + ":loadBundle basename=\"" + bundlePath + "\" var=\"" + var + "\" />"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
public void adoptBundle(XModelObject target, XModelObject object, Properties p) {
if(p == null) return;
String bundle = getBundle(object);
int pos = -1;
try {
String s = p == null ? null : p.getProperty("pos"); //$NON-NLS-1$
if(s != null && s.length() > 0) pos = Integer.parseInt(s);
} catch (NumberFormatException e) {
JsfUiPlugin.getPluginLog().logError(e);
}
SourceViewer viewer = (SourceViewer)p.get("viewer"); //$NON-NLS-1$
if(viewer == null || viewer.getDocument() == null) return;
JSPTokenizer tokenizer = new JSPTokenizer();
Token root = tokenizer.parse(viewer.getDocument());
int contextIndex = getContextIndex(tokenizer, pos);
String start = bundle;
if (contextIndex == 1) {
String jsfCorePrefix = JSPAdoptHelper.getPrefixForURI(root, JSF_CORE_TAGLIB_URI, JSF_CORE_TAGLIB_PREFIX_DEFAULT);
start = createLoadBundleTag(jsfCorePrefix, bundle, "|"); //$NON-NLS-1$
}
p.setProperty("start text", start); //$NON-NLS-1$
p.setProperty("end text", ""); //$NON-NLS-1$ //$NON-NLS-2$
}
private final static String JSF_CORE_TAGLIB_URI = "http://java.sun.com/jsf/core"; //$NON-NLS-1$
private final static String JSF_CORE_TAGLIB_PREFIX_DEFAULT = "f"; //$NON-NLS-1$
private final static String JSF_HTML_TAGLIB_URI = "http://java.sun.com/jsf/html"; //$NON-NLS-1$
private final static String JSF_HTML_TAGLIB_PREFIX_DEFAULT = "h"; //$NON-NLS-1$
String getBundle(XModelObject file) {
String bundle = XModelObjectLoaderUtil.getResourcePath(file);
if(bundle == null) bundle = ""; //$NON-NLS-1$
if(bundle.endsWith(".properties")) bundle = bundle.substring(0, bundle.length() - 11); //$NON-NLS-1$
bundle = bundle.substring(1).replace('/', '.');
int i = bundle.indexOf('_');
if(i >= 0) bundle = bundle.substring(0, i);
return bundle;
}
}