/*******************************************************************************
* Copyright (c) 2005, 2012 eBay 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
*
*******************************************************************************/
package org.eclipse.vjet.eclipse.internal.ui.text.completion;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Platform;
import org.eclipse.dltk.mod.ui.DLTKUIPlugin;
import org.eclipse.dltk.mod.ui.PreferenceConstants;
import org.eclipse.dltk.mod.ui.text.completion.HTMLPrinter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.vjet.dsf.jst.BaseJstNode;
import org.eclipse.vjet.dsf.jst.FileBinding;
import org.eclipse.vjet.dsf.jst.IJstAnnotation;
import org.eclipse.vjet.dsf.jst.IJstMethod;
import org.eclipse.vjet.dsf.jst.IJstNode;
import org.eclipse.vjet.dsf.jst.IJstProperty;
import org.eclipse.vjet.dsf.jst.IJstType;
import org.eclipse.vjet.dsf.jst.JstSource;
import org.eclipse.vjet.dsf.jst.SimpleBinding;
import org.eclipse.vjet.dsf.jst.declaration.JstAnnotation;
import org.eclipse.vjet.dsf.jst.declaration.JstArg;
import org.eclipse.vjet.dsf.jst.declaration.JstModifiers;
import org.eclipse.vjet.dsf.jst.expr.AssignExpr;
import org.eclipse.vjet.dsf.jst.expr.JstArrayInitializer;
import org.eclipse.vjet.dsf.jst.term.JstIdentifier;
import org.eclipse.vjet.dsf.jst.token.IExpr;
import org.eclipse.vjet.dsf.jst.util.JstCommentHelper;
import org.eclipse.vjet.dsf.jstojava.translator.JsDocHelper;
import org.eclipse.vjet.eclipse.internal.ui.scriptdoc.JavaDoc2HTMLTextReader;
import org.eclipse.vjet.eclipse.ui.VjetUIPlugin;
import org.osgi.framework.Bundle;
/**
* Generate additial info for vjo cc proposal
*
*
*
*/
public class VjoProposalAditionalInfoGenerator {
private static final String PERS_FILENAME = "additionalCompletionTemplate.html"; //$NON-NLS-1$
private static String PERS_FOLDER = "ccAdditionalPanel";
public static String getAdditionalPropesalInfo(IJstNode node) {
String info = null;
String css = getCSSStyles();
List<String> allSupportedExplorers = new ArrayList<String>();
IJstProperty property = null;
IJstMethod method = null;
if (node instanceof IJstProperty) {
property = (IJstProperty) node;
} else if (node instanceof IJstMethod) {
method = (IJstMethod) node;
}
String briefInfo = "";
if (property != null && property.getOwnerType()!=null &&
isBindingOk(property.getOwnerType().getSource()) &&
property.getCommentLocations() != null &&
!node.getCommentLocations().isEmpty()) {
List<String> strings = JstCommentHelper.getCommentsAsString(node.getOwnerType(), node.getCommentLocations());
StringBuilder sb = new StringBuilder();
for(String str:strings){
if(str!=null)
sb.append(JsDocHelper.cleanJsDocComment(str));
sb.append("<br>");
}
info = sb.toString();
briefInfo = getElementBriefDesc(property);
fillAllSupportedExplorer(property, allSupportedExplorers);
} else {
if (((method != null) && (method.getDoc() != null))) {
info = method.getDoc().getComment();
briefInfo = getElementBriefDesc(method);
fillAllSupportedExplorer(method, allSupportedExplorers);
}else if(property != null && property.getDoc() != null) {
info = property.getDoc().getComment();
briefInfo = getElementBriefDesc(property);
fillAllSupportedExplorer(property, allSupportedExplorers);
}
}
if (info != null) {
try {
File persFile = getTemplateFile();
if (!persFile.exists()) {
try {
persFile.createNewFile();
} catch (IOException e) {
}
copyHtmlTemplateFromBundleToTemp();
copyIconsFromBundleToTemp();
}
// Replace the invalid character.
info = info.replace("/", "");
info = info.replace("*", "");
if (persFile != null) {
FileReader readerSuc = new FileReader(persFile);
JavaDoc2HTMLTextReader reader2 = new JavaDoc2HTMLTextReader(
readerSuc);
String wholeInfo = getString(reader2);
wholeInfo = wholeInfo.replace("<%=browserSupported%>",
getSupportedTypesStirng(allSupportedExplorers,
"BrowserType."));
String domLevel = getSupportedTypesStirng(
allSupportedExplorers, "DomLevel.");
if (domLevel.length() > 0) {
wholeInfo = wholeInfo.replace("<%=DOMLevel%>",
"<b>DOM level</b><br>"
+ getSupportedTypesStirng(
allSupportedExplorers,
"DomLevel.") + "<br>");
}else{
wholeInfo = wholeInfo.replace("<%=DOMLevel%>",
"");
}
wholeInfo = wholeInfo.replace("<%=MinJSVersion%>",
translateCharacterToNumber(getSupportedTypesStirng(
allSupportedExplorers, "JsVersion.")));
wholeInfo = wholeInfo.replace("<%=briefInfo%>", briefInfo);
wholeInfo = wholeInfo.replace("<%=images%>",
getIcon(allSupportedExplorers));
wholeInfo = wholeInfo.replace("<%=description%>", info);
// Add the css and HTML tags at the beginning and
// end.
StringBuffer buffer = new StringBuffer();
HTMLPrinter.insertPageProlog(buffer, 0, css);
buffer.append(wholeInfo);
HTMLPrinter.addPageEpilog(buffer);
wholeInfo = buffer.toString();
return wholeInfo;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return info;
}
private static boolean isBindingOk(JstSource source) {
if (source!=null &&
source.getBinding()!=null){
if(source.getBinding() instanceof FileBinding){
if(((FileBinding)source.getBinding()).getFile()!=null){
return true;
}else{
return false;
}
}
else if(source.getBinding() instanceof SimpleBinding){
if(((SimpleBinding)source.getBinding()).toText()!=null){
return true;
}else{
return false;
}
}
}
return false;
}
private static String fgCSSStyles;
private static String getCSSStyles() {
if (fgCSSStyles == null) {
Bundle bundle = Platform.getBundle(VjetUIPlugin.PLUGIN_ID);
URL url = bundle.getEntry("/DocumentationHoverStyleSheet.css"); //$NON-NLS-1$
if (url != null) {
try {
url = FileLocator.toFileURL(url);
BufferedReader reader = new BufferedReader(
new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer(200);
String line = reader.readLine();
while (line != null) {
buffer.append(line);
buffer.append('\n');
line = reader.readLine();
}
fgCSSStyles = buffer.toString();
} catch (IOException ex) {
DLTKUIPlugin.log(ex);
}
}
}
String css = fgCSSStyles;
if (css != null) {
FontData fontData = JFaceResources.getFontRegistry().getFontData(
PreferenceConstants.APPEARANCE_DOCUMENTATION_FONT)[0];
css = HTMLPrinter.convertTopLevelFont(css, fontData);
}
return css;
}
/**
* Gets the reader content as a String
*/
private static String getString(Reader reader) {
StringBuffer buf = new StringBuffer();
char[] buffer = new char[1024];
int count;
try {
while ((count = reader.read(buffer)) != -1)
buf.append(buffer, 0, count);
} catch (IOException e) {
return null;
}
return buf.toString();
}
public static String getElementBriefDesc(IJstProperty property) {
StringBuffer buffer = new StringBuffer();
buffer.append(property.getOwnerType().getName() + "\n");
// buffer.append("<dl><dt>");
buffer.append(getModifierListStr(property.getModifiers()) + " <b>");
buffer.append(property.getName() + "</b> ");
// buffer.append("</dt><dd></dd></dl>");
return buffer.toString();
}
public static String getElementBriefDesc(IJstMethod method) {
StringBuffer buffer = new StringBuffer();
// buffer.append("<dl><dt>");
String rtnTypeName = "";
IJstType rtnType = method.getRtnType();
if(rtnType!=null){
rtnTypeName = rtnType.getName();
}
buffer.append( " <b>" + rtnTypeName + "</b> ");
buffer.append(getModifierListStr(method.getModifiers()) + " "
+ method.getName());
// buffer.append("</dt></dl>");
buffer.append("(" + combineParameters(method) + ")");
return buffer.toString();
}
/**
* @param method
* @return
*/
private static String combineParameters(IJstMethod method) {
String par = "";
if (method != null) {
List<JstArg> args = method.getArgs();
String comma = "";
int i = 0;
for (JstArg arg : args) {
if (i != 0) {
comma = ", ";
}
par += comma + arg.getType().getSimpleName() + " "
+ arg.getName();
i++;
}
}
return par;
}
public static String getModifierListStr(JstModifiers jstModifiers) {
List<BaseJstNode> list = jstModifiers.getChildren();
if (list == null || list.isEmpty()) {
return "";
}
StringBuffer buffer = new StringBuffer();
Iterator<BaseJstNode> it = list.iterator();
while (it.hasNext()) {
BaseJstNode node = it.next();
buffer.append("");
}
return buffer.toString();
}
private static String getSupportedTypesStirng(List<String> supportedTypes,
String type) {
String imageLine = "";
String comma = "";
int i = 0;
for (Object oneType : supportedTypes) {
if (((String) oneType).startsWith(type)) {
if (i != 0) {
comma = ", ";
}
imageLine += comma
+ ((String) oneType).substring(type.length());
i++;
}
}
boolean noBrowserInfo = noBrowserInfo(supportedTypes);
if (noBrowserInfo && "BrowserType.".equals(type)) {
//imageLine = "FIREFOX,IE,OPERA,SAFARI,CHROME";
}
return imageLine;
}
/**
* @param supportedTypes
* @return
*/
private static String getIcon(List<String> supportedTypes) {
String imageLine = "";
String path = getDir().getPath();
boolean noBrowserInfo = false;
if (getDescOfSupport(supportedTypes, "FIREFOX").trim().length() > 0
|| noBrowserInfo) {
imageLine += "<img aligh=\"right\" src=\""
+ path
+ "/firefox.gif\" height=\"25\" width=\"25\" border=\"0\" title=\""
+ getDescOfSupport(supportedTypes, "MOZILLA") + "\">";
}
if (getDescOfSupport(supportedTypes, "IE").trim().length() > 0
|| noBrowserInfo) {
imageLine += "<img aligh=\"right\" src=\""
+ path
+ "/ie.gif\" height=\"25\" width=\"25\" border=\"0\" title=\""
+ getDescOfSupport(supportedTypes, "IE") + "\">";
}
if (getDescOfSupport(supportedTypes, "OPERA").trim().length() > 0
|| noBrowserInfo) {
imageLine += "<img aligh=\"right\" src=\""
+ path
+ "/opera.gif\" height=\"25\" width=\"25\" border=\"0\" title=\""
+ getDescOfSupport(supportedTypes, "OPERA") + "\">";
}
if (getDescOfSupport(supportedTypes, "SAFARI").trim().length() > 0
|| noBrowserInfo) {
imageLine += "<img aligh=\"right\" src=\""
+ path
+ "/safari.gif\" height=\"25\" width=\"25\" border=\"0\" title=\""
+ getDescOfSupport(supportedTypes, "SAFARI") + "\">";
}
if (getDescOfSupport(supportedTypes, "CHROME").trim().length() > 0
|| noBrowserInfo) {
imageLine += "<img aligh=\"right\" src=\""
+ path
+ "/chrome.gif\" height=\"25\" width=\"25\" border=\"0\" title=\""
+ getDescOfSupport(supportedTypes, "CHROME") + "\">";
}
return imageLine;
}
/**
* @param supportedTypes
* @return
*/
private static boolean noBrowserInfo(List supportedTypes) {
boolean noBrowserInfo = true;
for (Object type : supportedTypes) {
if (((String) type).contains("BrowserType.")) {
noBrowserInfo = false;
break;
}
}
return noBrowserInfo;
}
/**
* @param jstElement
* @return
*/
private static List<String> fillAllSupportedExplorer(Object jstElement,
List<String> allSupportedExplorers) {
if (jstElement instanceof IJstProperty) {
List<IJstAnnotation> annotations = ((IJstProperty) jstElement).getAnnotations();
getExplorerInfoFromAnnotation(allSupportedExplorers, annotations);
if (annotations.size() == 0) {
fillAllSupportedExplorer(((IJstProperty) jstElement)
.getOwnerType(), allSupportedExplorers);
}
} else if (jstElement instanceof IJstMethod) {
List<IJstAnnotation> annotations = ((IJstMethod) jstElement).getAnnotations();
getExplorerInfoFromAnnotation(allSupportedExplorers, annotations);
if (annotations.size() == 0) {
fillAllSupportedExplorer(((IJstMethod) jstElement)
.getOwnerType(), allSupportedExplorers);
}
} else if (jstElement instanceof IJstType) {
List<IJstAnnotation> annotations = ((IJstType) jstElement).getAnnotations();
getExplorerInfoFromAnnotation(allSupportedExplorers, annotations);
}
return allSupportedExplorers;
}
public static boolean isBrowserNoneNode(IJstNode node) {
if (!(node instanceof IJstMethod || node instanceof IJstProperty)) {
return false;
}
List<IJstAnnotation> annotations = node.getAnnotations();
if (annotations.size() != 1) {
return false;
}
List<String> allSupportedExplorers = new ArrayList<String>();
getExplorerInfoFromAnnotation(allSupportedExplorers, annotations);
if (allSupportedExplorers.size() != 0 && "BrowserType.NONE".equals(allSupportedExplorers.get(0))) {
return true;
} else {
return false;
}
}
/**
* @param allSupportedExplorers
* @param annotations
*/
static void getExplorerInfoFromAnnotation(
List<String> allSupportedExplorers, List<IJstAnnotation> annotations) {
for (Object annotation : annotations) {
if (annotation instanceof JstAnnotation
&& ("JsSupport".equals(((JstAnnotation) annotation)
.getName().getName())) ||
"BrowserSupport".equals(((JstAnnotation) annotation)
.getName().getName()) ||
"DOMSupport".equals(((JstAnnotation) annotation)
.getName().getName())) {
for (IExpr expr : ((JstAnnotation) annotation).values()) {
// array initializier
if(expr instanceof JstIdentifier){
String typeName = expr.toExprText();
if (!allSupportedExplorers
.contains(typeName)) {
allSupportedExplorers.add(typeName);
}
}
if(expr instanceof JstArrayInitializer){
JstArrayInitializer init = (JstArrayInitializer)expr;
String typeString = init.toExprText();
if (typeString.length() > 1) {
if (typeString.startsWith("[")
&& typeString.endsWith("]")) {
typeString = typeString.substring(1,
typeString.length() - 1);
}
String[] type = typeString.split(",");
for (String typeName : type) {
if (!allSupportedExplorers
.contains(typeName)) {
allSupportedExplorers.add(typeName);
}
}
}
}
if (expr instanceof AssignExpr) {
List<? extends IJstNode> supportTypes = ((AssignExpr) expr).getExpr()
.getChildren();
for (Object supportType : supportTypes) {
if (supportType instanceof JstIdentifier) {
String typeString = ((JstIdentifier) supportType)
.getParentNode().toString();
if (typeString.length() > 1) {
if (typeString.startsWith("[")
&& typeString.endsWith("]")) {
typeString = typeString.substring(1,
typeString.length() - 1);
}
String[] type = typeString.split(",");
for (String typeName : type) {
if (!allSupportedExplorers
.contains(typeName)) {
allSupportedExplorers.add(typeName);
}
}
}
}
}
}
}
}
}
}
/**
* Copy the html template to temporary folder.
*/
private static void copyHtmlTemplateFromBundleToTemp() {
String[] htmlFiles = new String[] { PERS_FILENAME };
for (String file : htmlFiles) {
copyFileFromBundleToTemp("templates", file);
}
}
/**
* Copy current icons to temporary folder.
*/
private static void copyIconsFromBundleToTemp() {
String[] icons = new String[] { "chrome.gif", "firefox.gif", "ie.gif",
"opera.gif", "safari.gif" };
for (String icon : icons) {
copyFileFromBundleToTemp("icons", icon);
}
}
private static File getDir() {
File dir = VjetUIPlugin.getDefault().getStateLocation().toFile();
dir = new File(dir, PERS_FOLDER);
if (!dir.exists()) {
dir.mkdirs();
}
return dir;
}
private static File getTemplateFile() {
File dir = getDir();
File persFile = new File(dir, PERS_FILENAME);
return persFile;
}
/**
* Copy specified icon to temporary folder.
*
* @param folderName
* TODO
*/
private static void copyFileFromBundleToTemp(String folderName,
String fileName) {
try {
File persFile = new File(getDir(), fileName);
URL url = VjetUIPlugin.getDefault().getBundle().getEntry(
folderName + "/" + fileName);
InputStream stream = url.openStream();
byte[] bs = new byte[stream.available()];
stream.read(bs);
FileOutputStream fop = new FileOutputStream(persFile);
if (persFile.exists()) {
fop.write(bs);
fop.flush();
fop.close();
}
} catch (IOException e) {
}
}
/**
* @param supportedTypes
* @param type
* @return
*/
private static String getDescOfSupport(List<String> supportedTypes,
String type) {
for (String everyType : supportedTypes) {
if (everyType.contains(type)) {
return everyType;
}
}
return "";
}
/**
* @param desc
* @return
*/
private static String translateCharacterToNumber(String desc) {
if (desc != null) {
String[] numbers = { "_ZERO", "_ONE", "_TWO", "_THREE", "_FOUR",
"_FIVE", "_SIX", "_SEVEN", "_EIGHT", "_NINE" };
for (int i = 0; i < numbers.length; i++) {
if (desc.contains(numbers[i])) {
desc = desc.replace(numbers[i], String.valueOf(i));
}
}
if (desc.contains("_DOT")) {
desc = desc.replace("_DOT", ".");
}
}
return desc;
}
/**
* @param baseUrl
* @param create
*/
private static void generateTempFolder(URL baseUrl, boolean create) {
if (baseUrl == null) {
return;
}
try {
// make sure the directory exists
URL url = new URL(baseUrl, PERS_FOLDER);
File dir = new File(url.getFile());
if (!dir.exists() && create) {
dir.mkdir();
}
} catch (IOException e) {
}
}
}