/** * This file Copyright (c) 2005-2008 Aptana, Inc. This program is * dual-licensed under both the Aptana Public License and the GNU General * Public license. You may elect to use one or the other of these licenses. * * This program is distributed in the hope that it will be useful, but * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or * NONINFRINGEMENT. Redistribution, except as permitted by whichever of * the GPL or APL you select, is prohibited. * * 1. For the GPL license (GPL), you can redistribute and/or modify this * program under the terms of the GNU General Public License, * Version 3, as published by the Free Software Foundation. You should * have received a copy of the GNU General Public License, Version 3 along * with this program; if not, write to the Free Software Foundation, Inc., 51 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Aptana provides a special exception to allow redistribution of this file * with certain other free and open source software ("FOSS") code and certain additional terms * pursuant to Section 7 of the GPL. You may view the exception and these * terms on the web at http://www.aptana.com/legal/gpl/. * * 2. For the Aptana Public License (APL), this program and the * accompanying materials are made available under the terms of the APL * v1.0 which accompanies this distribution, and is available at * http://www.aptana.com/legal/apl/. * * You may view the GPL, Aptana's exception and additional terms, and the * APL in the file titled license.html at the root of the corresponding * plugin containing this source file. * * Any modifications to this file must keep this entire header intact. */ package com.aptana.ide.editors.views.profiles; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.aptana.ide.core.FileUtils; import com.aptana.ide.core.StringUtils; import com.aptana.ide.core.ui.CoreUIUtils; import com.aptana.ide.parsing.IParseState; import com.aptana.ide.parsing.nodes.IParseNode; /** * * @author Ingo Muschenetz * */ public class ProfilesViewHelper { /** * * @param base * @param text * @return */ public static String[] addSDocFromJavaScriptSource(File base, String text) { URL baseFile = FileUtils.uriToURL(CoreUIUtils.getURI(base)); return addSDocFromJavaScriptSource(baseFile, text); } /** * * @param base * @param text * @return */ public static String[] addSDocFromJavaScriptSource(URL base, String text) { List<String> fileList = new ArrayList<String>(); int commentStart = text.indexOf("/*"); //$NON-NLS-1$ while (commentStart != -1) { int commentEnd = text.indexOf("*/", commentStart + 2); //$NON-NLS-1$ if (commentEnd != -1) { // String comment = text.substring(commentStart, commentEnd + // 2); Pattern p = Pattern.compile("@sdoc\\s+([^\r\n]+)"); //$NON-NLS-1$ Matcher matcher = p.matcher(text); String matchedString = ""; //$NON-NLS-1$ while (matcher.find()) { matchedString = matcher.group(1); } if (matchedString != "") { //$NON-NLS-1$ // String filename = matchedString.replace("\\s+$", ""); String filename = matchedString.trim(); if (filename.charAt(0) != '/' || filename.indexOf(":") == -1) { //$NON-NLS-1$ filename = CoreUIUtils.joinURI(base, filename); } // save original source up to but not including the comment fileList.add(CoreUIUtils.getURI(filename)); } commentStart = text.indexOf("/*", commentEnd + 2); //$NON-NLS-1$ } else { break; } } return fileList.toArray(new String[fileList.size()]); } /** * * @param base * @param text * @param parseState * @return */ public static String[] addScriptTagsFromHTMLSource(File base, String text, IParseState parseState) { URL baseFile = FileUtils.uriToURL(CoreUIUtils.getURI(base)); return addScriptTagsFromHTMLSource(baseFile, text, parseState); } /** * * @param base * @param text * @param parseState * @return */ public static String[] addScriptTagsFromHTMLSource(URL base, String text, IParseState parseState) { List<String> fileList = new ArrayList<String>(); IParseNode results = parseState.getParseResults(); IParseNode[] current = results.getChildren(); IQueue queue = new ArrayQueue(); List<String> srcs = new ArrayList<String>(); for (int i = 0; i < current.length; i++) { queue.enqueue(current[i]); } while (queue.size() > 0) { IParseNode node = (IParseNode) queue.dequeue(); IParseNode[] children = node.getChildren(); for (int i = 0; i < children.length; i++) { IParseNode child = children[i]; if ("script".equals(child.getText())) { //$NON-NLS-1$ boolean hasFile = false; String filename = child.getAttribute("src"); //$NON-NLS-1$ filename = makeHttpUrl(filename); // [IM] added for bug #4735 String aSrc = ""; //$NON-NLS-1$ for (int j = 0; j < srcs.size(); j++) { aSrc = srcs.get(j); if (aSrc == filename) { hasFile = true; break; } } if (hasFile == false) { srcs.add(filename); } } else { queue.enqueue(child); } } } for (int i = 0; i < srcs.size(); i++) { String src = srcs.get(i); if (src != null && src.length() > 0) { String source = StringUtils.trimStringQuotes(src); source = stripQuerystring(source); // see if the source ref is absolute or relative if (!CoreUIUtils.isURI(source) && source.charAt(0) != '/') { source = CoreUIUtils.joinURI(base, source); } String uri = CoreUIUtils.getURI(source); fileList.add(uri); String sdocFile = findScriptDocFile(uri); if (sdocFile != null) { fileList.add(CoreUIUtils.getURI(sdocFile)); } URL url = FileUtils.uriToURL(uri); if(url != null) { String[] subFiles = addScriptFromJavaScriptSource(url); fileList.addAll(Arrays.asList(subFiles)); } } } // Remove duplicate entries return fileList.toArray(new String[fileList.size()]); } /** * * @param file * @return */ public static String[] addSDocFromJavaScriptSource(URL url) { URL basePath = getBasePath(url); try { String text = FileUtils.readContent(url); if(text != null) { return addSDocFromJavaScriptSource( basePath, text); } else { return new String[0]; } } catch(IOException ex) { return new String[0]; } } public static URL getBasePath(URL url) { return CoreUIUtils.trimURLSegments(url, 1); } public static URL getBasePath(String uri) { URI uri2; try { uri2 = new URI(uri); URL url = uri2.toURL(); return getBasePath(url); } catch (MalformedURLException e) { e.printStackTrace(); return null; } catch (URISyntaxException e) { e.printStackTrace(); return null; } } /** * * @param file * @return */ public static String[] addScriptFromJavaScriptSource(URL url) { URL basePath = getBasePath(url); String text; try { text = FileUtils.readContent(url); if (text != null) { return addScriptFromJavaScriptSource(basePath, text); } } catch (IOException e) { return new String[0]; } return new String[0]; } /** * * @param base * @param text * @return */ public static String[] addScriptFromJavaScriptSource(File base, String text) { URL baseFile = FileUtils.uriToURL(CoreUIUtils.getURI(base)); return addScriptFromJavaScriptSource(baseFile, text); } /** * * @param base * @param text * @return */ public static String[] addScriptFromJavaScriptSource(URL base, String text) { List<String> fileList = new ArrayList<String>(); Pattern pattern = Pattern .compile( "^MochiKit\\.MochiKit\\.SUBMODULES\\s*=\\s*\\[[\\r\\n]+([^\\]]+)\\]", //$NON-NLS-1$ Pattern.MULTILINE); Matcher matcher = pattern.matcher(text); String names = ""; //$NON-NLS-1$ while (matcher.find()) { names = matcher.group(1); } pattern = Pattern.compile("\"([^\"]+)\""); //$NON-NLS-1$ matcher = pattern.matcher(names); List<String> mochikitNames = new ArrayList<String>(); while (matcher.find()) { mochikitNames.add(matcher.group(1)); } // see if they referenced any sdoc files in the code via @sdoc tag String[] sdocs = ProfilesViewHelper.addSDocFromJavaScriptSource(base, text); fileList.addAll(Arrays.asList(sdocs)); for (int i = 0; i < mochikitNames.size(); i++) { String source = CoreUIUtils.joinURI(base, mochikitNames.get(i) + ".js"); //$NON-NLS-1$ fileList.add(CoreUIUtils.getURI(source)); // see if they referenced any sdoc files in the code via @sdoc tag URL u = FileUtils.uriToURL(source); if(u != null) { String[] subFiles = addSDocFromJavaScriptSource(u); fileList.addAll(Arrays.asList(subFiles)); } // see if there are any sdoc files along side this file String sdocFile = findScriptDocFile(source); if (sdocFile != null) { fileList.add(CoreUIUtils.getURI(sdocFile)); } } return fileList.toArray(new String[fileList.size()]); } /** * * @param source * @return */ public static String findScriptDocFile(String fileName) { String baseName = CoreUIUtils.getURI(FileUtils.stripExtension(fileName)); String sdocName = baseName + ".sdoc"; //$NON-NLS-1$ URL sdocURL = FileUtils.uriToURL(sdocName); if (isValidURL(sdocURL)) { return sdocURL.toString(); } else { return null; } } /** * * @param source * @return */ public static String stripQuerystring(String source) { int tmp = source.indexOf("?"); //$NON-NLS-1$ if (tmp > -1) { source = source.substring(0, tmp); } return source; } /** * Is the URL a valid URL? * @param f * @return */ public static boolean isValidURL(URL url) { if(url == null) { return false; } try { if(FileUtils.isFileURL(url)) { File file = FileUtils.urlToFile(url); return file.exists() && file.isFile() && file.canRead(); } else { InputStream is = url.openStream(); is.close(); return true; } } catch (IOException e) { return false; } } /** * Treat urls beginning with "//" as http:// * @param url * @return */ public static String makeHttpUrl(String url) { if(url != null && url.startsWith("//")) //$NON-NLS-1$ { return "http:" + url; //$NON-NLS-1$ } else { return url; } } }