/** * 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.editor.js.parsing; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import com.aptana.ide.editors.unified.LanguageRegistry; import com.aptana.ide.parsing.IParser; /** * @author Kevin Lindsey */ public class JSLanguageRegistry { private static String TAG_PARSER = "parser"; //$NON-NLS-1$ private static String TAG_SCANNER = "scanner"; //$NON-NLS-1$ private static String TAG_PI_LANGUAGE = "pi-language"; //$NON-NLS-1$ private static String TAG_SINGLE_LINE_COMMENT_LANGUAGE = "single-line-comment-language"; //$NON-NLS-1$ private static String TAG_MULTI_LINE_COMMENT_LANGUAGE = "multi-line-comment-language"; //$NON-NLS-1$ private static String TAG_DOCUMENTATION_COMMENT_LANGUAGE = "documentation-comment-language"; //$NON-NLS-1$ // parser attribute private static String ATTR_LANGUAGE = "language"; //$NON-NLS-1$ //private static String ATTR_PARSER = "parser"; //$NON-NLS-1$ // pi-language attribute private static String ATTR_PI_NAME = "pi-name"; //$NON-NLS-1$ private static String SINGLE_LINE_COMMENT_KEY = "//"; //$NON-NLS-1$ private static String MULTI_LINE_COMMENT_KEY = "/*"; //$NON-NLS-1$ private static String DOCUMENTATION_COMMENT_KEY = "/**"; //$NON-NLS-1$ private Map<String, IParser> _parserByMimeType; private Map<String, IParser> _scannerByMimeType; /** * ElementRegistry */ public JSLanguageRegistry() { this._parserByMimeType = new HashMap<String, IParser>(); this._scannerByMimeType = new HashMap<String, IParser>(); } /** * getDocumentationCommentParser * * @return IParser */ public IParser getDocumentationCommentParser() { return this.getParser(DOCUMENTATION_COMMENT_KEY); } /** * getDocumentationCommentScanner * * @return IParser */ public IParser getDocumentationCommentScanner() { return this.getScanner(DOCUMENTATION_COMMENT_KEY); } /** * getMultiLineCommentParser * * @return IParser */ public IParser getMultiLineCommentParser() { return this.getParser(MULTI_LINE_COMMENT_KEY); } /** * getMultiLineCommentScanner * * @return IParser */ public IParser getMultiLineCommentScanner() { return this.getScanner(MULTI_LINE_COMMENT_KEY); } /** * getParser * * @param key * @return IParser */ public IParser getParser(String key) { IParser result = null; if (this._parserByMimeType.containsKey(key)) { result = this._parserByMimeType.get(key); } return result; } /** * getPILanguage * * @param processInstructionName * @return IParser */ public IParser getProcessingInstructionLanguage(String processInstructionName) { return this.getParser(processInstructionName); } /** * getProcessingInstructionScanner * * @param processInstructionName * @return IParser */ public IParser getProcessingInstructionScanner(String processInstructionName) { return this.getScanner(processInstructionName); } /** * getScanner * * @param key * @return IParser */ public IParser getScanner(String key) { IParser result = null; if (this._scannerByMimeType.containsKey(key)) { result = this._scannerByMimeType.get(key); } return result; } /** * getSingleLineCommentParser * * @return IParser */ public IParser getSingleLineCommentParser() { return this.getParser(SINGLE_LINE_COMMENT_KEY); } /** * getSingleLineCommentScanner * * @return IParser */ public IParser getSingleLineCommentScanner() { return this.getScanner(SINGLE_LINE_COMMENT_KEY); } /** * loadFromExtension * * @param extension * @return IParser[] */ public IParser[] loadParsersFromExtension(IExtension extension) { IConfigurationElement[] elements = extension.getConfigurationElements(); List<IParser> parsers = new ArrayList<IParser>(); for (IConfigurationElement element : elements) { if (element.getName().equals(TAG_PARSER)) { processElement(parsers, element, false); } } return parsers.toArray(new IParser[parsers.size()]); } /** * loadScannersFromExtension * * @param extension * @return IParser[] */ public IParser[] loadScannersFromExtension(IExtension extension) { IConfigurationElement[] elements = extension.getConfigurationElements(); List<IParser> parsers = new ArrayList<IParser>(); for (IConfigurationElement element : elements) { if (element.getName().equals(TAG_SCANNER)) { processElement(parsers, element, true); } } return parsers.toArray(new IParser[parsers.size()]); } /** * processElement * * @param parsers * @param element * @param isScanner */ private void processElement(List<IParser> parsers, IConfigurationElement element, boolean isScanner) { String language = element.getAttribute(ATTR_LANGUAGE); if (language != null && language.length() > 0) { // create parser instance //parser = (IParser) element.createExecutableExtension(ATTR_PARSER); IParser parser; if (isScanner) { parser = LanguageRegistry.createScanner(language); } else { parser = LanguageRegistry.createParser(language); } // register all pi-languages using this parser this.registerPILanguages(element.getChildren(TAG_PI_LANGUAGE), parser, isScanner); // register all single-line comment languages this.registerCommentLanguages( SINGLE_LINE_COMMENT_KEY, element.getChildren(TAG_SINGLE_LINE_COMMENT_LANGUAGE), parser, isScanner ); // register all multi-line comment languages this.registerCommentLanguages( MULTI_LINE_COMMENT_KEY, element.getChildren(TAG_MULTI_LINE_COMMENT_LANGUAGE), parser, isScanner ); // register all document comment languages this.registerCommentLanguages( DOCUMENTATION_COMMENT_KEY, element.getChildren(TAG_DOCUMENTATION_COMMENT_LANGUAGE), parser, isScanner ); // add parser for our return result parsers.add(parser); } } /** * registerPILanguage * * @param element * @param parsers * @param isScanner */ private void registerCommentLanguages(String key, IConfigurationElement[] elements, IParser parser, boolean isScanner) { for (int i = 0; i < elements.length; i++) { // get pi-language IConfigurationElement element = elements[i]; // build full pi-name String piName = "<?" + element.getAttribute(ATTR_PI_NAME); //$NON-NLS-1$ // register transition if (isScanner) { this.registerScanner(piName, parser); } else { this.registerParser(piName, parser); } } } /** * registerParser * * @param key * @param parser */ private void registerParser(String key, IParser parser) { this._parserByMimeType.put(key, parser); } /** * registerPILanguage * * @param element * @param parsers * @param isScanner */ private void registerPILanguages(IConfigurationElement[] elements, IParser parser, boolean isScanner) { for (int i = 0; i < elements.length; i++) { // get pi-language IConfigurationElement element = elements[i]; // build full pi-name String piName = "<?" + element.getAttribute(ATTR_PI_NAME); //$NON-NLS-1$ // register transition if (isScanner) { this.registerScanner(piName, parser); } else { this.registerParser(piName, parser); } } } /** * registerScanner * * @param key * @param parser */ private void registerScanner(String key, IParser parser) { this._scannerByMimeType.put(key, parser); } }