/**
* 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.unified.colorizer;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.osgi.framework.Bundle;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import com.aptana.ide.core.IdeLog;
import com.aptana.ide.core.StringUtils;
import com.aptana.ide.editors.UnifiedEditorsPlugin;
import com.aptana.ide.editors.unified.InstanceCreator;
import com.aptana.ide.editors.unified.LanguageRegistry;
import com.aptana.ide.editors.unified.UnifiedColorManager;
import com.aptana.ide.lexer.IToken;
import com.aptana.ide.lexer.ITokenList;
import com.aptana.sax.AttributeSniffer;
import com.aptana.sax.Schema;
import com.aptana.sax.SchemaBuilder;
import com.aptana.sax.SchemaInitializationException;
import com.aptana.sax.ValidatingReader;
import com.aptana.xml.IErrorHandler;
/**
* @author Kevin Sawicki (ksawicki@aptana.com)
*/
public class ColorizerReader extends ValidatingReader
{
/**
* Schema resource.
*/
private static final String SCHEMA = "/com/aptana/ide/editors/resources/ColorizationSchema.xml"; //$NON-NLS-1$
private static final Pattern PARSE_ERROR_LINE_NUMBER = Pattern.compile(" line (\\d+)"); //$NON-NLS-1$
private String currentCategory;
private IToken currentToken;
private String mimeType;
private Locator locator;
private IErrorHandler errorHandler;
/**
* Default token list.
*/
private ITokenList defaultTokenList;
private LanguageColorizer colorizer;
// String category name -> Map token types to tokens
private Map<String, Map<String, IToken>> categoriesToToken;
// String style id -> Colorization style object
private Map<String, ColorizationStyle> styles;
// mime types to pref ids
private Map<String, String> ids;
// mime type to colorization file urls
private Map<String, URL> urls;
// IToken token -> String category || String style id
private Map<Object, String> waitingElements;
// Region -> Token
private Map<Region, IToken> regionsToToken;
private Map<String, InstanceCreator> instanceCreators = new HashMap<String, InstanceCreator>();
private List<IColorizerHandler> handlers = new ArrayList<IColorizerHandler>();
/**
* Register colorizer
*/
protected boolean registerColorizer;
/**
* Creates a new colorizer reader and parses all colorizations found in the directory.
*/
public ColorizerReader()
{
this(null);
}
/**
* Creates a new colorizer reader and parses all colorizations found in the directory.
*
* @param tokenList -
* token list to use.
*/
public ColorizerReader(ITokenList tokenList)
{
categoriesToToken = new HashMap<String, Map<String, IToken>>();
styles = new HashMap<String, ColorizationStyle>();
ids = new HashMap<String, String>();
urls = new HashMap<String, URL>();
waitingElements = new HashMap<Object, String>();
regionsToToken = new HashMap<Region, IToken>();
this.defaultTokenList = tokenList;
// get schema for our documentation XML format
this._schema = createSchema();
}
/**
* Loads and registers all the colorizers contributed via extension point
*/
public void loadExtensionPointColorizers()
{
registerColorizer = true;
IExtensionRegistry reg = Platform.getExtensionRegistry();
IExtensionPoint ep = reg.getExtensionPoint(UnifiedEditorsPlugin.COLORIZATION_EXTENSION_POINT);
if (ep == null)
{
return;
}
IExtension[] extensions = ep.getExtensions();
for (int i = 0; i < extensions.length; i++)
{
try
{
String pluginID = extensions[i].getContributor().getName();
IConfigurationElement[] elements = extensions[i].getConfigurationElements();
for (IConfigurationElement element : elements)
{
if( !LanguageRegistry.isActivityEnabled(element)){
//Do nothing because this extension should not work.
continue;
}
else if (ColorizationConstants.COLORIZATION_ELEMENT.equals(element.getName()))
{
String colorizationFile = element.getAttribute(ColorizationConstants.FILE_ATTR);
final String id = element.getAttribute(ColorizationConstants.ID_ATTR);
if (colorizationFile != null && id != null && id.length() > 0)
{
Bundle bundle = Platform.getBundle(pluginID);
final URL filePath = bundle.getEntry(colorizationFile);
if (filePath != null)
{
InstanceCreator creator = new InstanceCreator(null, null)
{
public Object createInstance()
{
return loadColorizationFromURL(filePath, id, false);
}
};
AttributeSniffer sniffer = new AttributeSniffer(ColorizationConstants.COLORIZER,
ColorizationConstants.LANGUAGE);
sniffer.read(filePath.openStream());
if (sniffer.getMatchedValue() != null)
{
String language = sniffer.getMatchedValue();
instanceCreators.put(language, creator);
}
}
}
}
else if (ColorizationConstants.HANDLER_ELEMENT.equals(element.getName()))
{
String handler = element.getAttribute(ColorizationConstants.CLASS_ATTR);
if (handler != null)
{
try
{
Object obj = element.createExecutableExtension(ColorizationConstants.CLASS_ATTR);
if (obj instanceof IColorizerHandler)
{
IColorizerHandler colorizerHandler = (IColorizerHandler) obj;
handlers.add(colorizerHandler);
}
}
catch (CoreException e)
{
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), Messages.ColorizerReader_ERR_ErrorCreatingColorizerHandler,
e);
}
}
}
}
}
catch (InvalidRegistryObjectException e)
{
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), Messages.ColorizerReader_ERROR_EXTENSION_POINT);
}
catch (Exception e)
{
// We want to catch everything so one colorizers errors doesn't affect anothers
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), e.getMessage());
}
}
}
/**
* @param stream
* @param register
* @return - language colorizer or null if creation failed
*/
public LanguageColorizer loadLanguageColorizer(InputStream stream, boolean register)
{
registerColorizer = register;
colorizer = null;
try
{
this.loadXML(stream);
}
catch (Exception e)
{
colorizer = null;
}
return colorizer;
}
/**
* Imports a colorization and saves it to preference and global registry.
*
* @param file -
* imported colorization
* @param mimeType
*/
public void importColorization(File file, String mimeType)
{
InputStream stream = null;
try
{
String id = ids.get(mimeType);
if (id != null)
{
IPreferenceStore store = UnifiedEditorsPlugin.getDefault().getPreferenceStore();
String content = store.getString(id);
stream = file.toURL().openStream();
this.loadXML(stream);
if (mimeType != null)
{
store.setValue(id, content);
}
}
}
catch (Exception e1)
{
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), Messages.ColorizerReader_ERROR_IMPORTING);
}
finally
{
try
{
if (stream != null)
{
stream.close();
}
}
catch (IOException e)
{
}
}
}
/**
* Imports a colorization and returns it as a language colorizer.
*
* @param file -
* imported colorization
* @return imported language colorizer.
*/
public LanguageColorizer importColorization(File file)
{
InputStream stream = null;
try
{
stream = new FileInputStream(file);
registerColorizer = false;
LanguageColorizer colorizer = this.loadXML(stream);
return colorizer;
}
catch (Exception e1)
{
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), Messages.ColorizerReader_ERROR_IMPORTING);
}
finally
{
try
{
if (stream != null)
{
stream.close();
}
}
catch (IOException e)
{
}
}
return null;
}
/**
* Loads a colorization from the preference store
*
* @param id
* @param register
* @return - language colorizer
*/
public LanguageColorizer loadColorization(String id, boolean register)
{
registerColorizer = register;
colorizer = null;
mimeType = null;
try
{
IPreferenceStore store = UnifiedEditorsPlugin.getDefault().getPreferenceStore();
String content = store.getString(id);
InputStream stream = null;
if (content.length() > 0)
{
stream = new ByteArrayInputStream(content.getBytes());
this.loadXML(stream);
if (mimeType != null)
{
setPreferenceId(mimeType, id);
store.setValue(id, content);
}
}
}
catch (Exception e)
{
colorizer = null;
}
return colorizer;
}
/**
* Loads a colorization file into the language registry
*
* @param url
* @param id
* @param useDefault
* @return - language colorizer
*/
public LanguageColorizer loadColorizationFromURL(URL url, String id, boolean useDefault)
{
InputStream stream = null;
colorizer = null;
mimeType = null;
try
{
IPreferenceStore store = UnifiedEditorsPlugin.getDefault().getPreferenceStore();
String content = store.getString(id);
if (content.length() > 0 && !useDefault)
{
stream = new ByteArrayInputStream(content.getBytes());
}
else
{
stream = url.openStream();
}
this.loadXML(stream);
if (mimeType != null)
{
setPreferenceId(mimeType, id);
urls.put(mimeType, url);
store.setValue(id, content);
}
}
catch (Exception e)
{
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), StringUtils.format(
Messages.ColorizerReader_ERROR_LOADING, id));
}
finally
{
try
{
if (stream != null)
{
stream.close();
}
}
catch (IOException e)
{
}
}
return colorizer;
}
/**
* Loads from XML.
*
* @param stream -
* stream.
* @return loaded colorizer.
*/
private LanguageColorizer loadXML(InputStream stream)
{
try
{
// create a new SAX factory class
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXParser saxParser = null;
// parse the XML file
saxParser = factory.newSAXParser();
saxParser.parse(stream, this);
return colorizer;
}
catch (Exception e)
{
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), Messages.ColorizerReader_ERR_ErrorParsingColorizationFile, e);
}
return null;
}
/**
* Get preference id for mime type
*
* @param mimeType
* @return id
*/
public String getPreferenceId(String mimeType)
{
return ids.get(mimeType);
}
/**
* @see org.xml.sax.helpers.DefaultHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator)
{
this.locator = locator;
}
/**
* sendWarning
*
* @param message
*/
private void sendWarning(String message)
{
if (this.errorHandler != null)
{
int line = this.locator.getLineNumber();
int column = this.locator.getColumnNumber();
if (line == -1)
{
Matcher m = PARSE_ERROR_LINE_NUMBER.matcher(message);
if (m.find())
{
line = Integer.parseInt(m.group(1));
}
else
{
line = 0;
}
}
this.errorHandler.handleWarning(line, column, message);
}
}
/**
* setErrorHandler
*
* @param errorHandler
*/
public void setErrorHandler(IErrorHandler errorHandler)
{
this.errorHandler = errorHandler;
}
/**
* sendError
*
* @param message
*/
private void sendError(String message)
{
if (this.errorHandler != null)
{
int line = this.locator.getLineNumber();
int column = this.locator.getColumnNumber();
if (line == -1)
{
Matcher m = PARSE_ERROR_LINE_NUMBER.matcher(message);
if (m.find())
{
line = Integer.parseInt(m.group(1));
}
else
{
line = 0;
}
}
this.errorHandler.handleError(line, column, message);
}
}
/**
* Parses the color format of the colorization file
*
* @param value -
* String color value
* @return - RGB object of parsed color string
*/
private RGB parseRGB(String value)
{
String original = value;
RGB rgb = new RGB(0, 0, 0);
try
{
value = value.trim();
if (value.startsWith("rgb")) //$NON-NLS-1$
{
value = value.substring(4, value.length());
value = value.substring(0, value.length() - 1);
String[] rgbs = value.split(","); //$NON-NLS-1$
if (rgbs.length >= 3)
{
try
{
rgb.red = Integer.parseInt(rgbs[0].trim());
}
catch (NumberFormatException e)
{
sendError(Messages.ColorizerReader_ERR_InvalidRedValueForRGBColor + original + "\""); //$NON-NLS-1$
IdeLog.logError(UnifiedEditorsPlugin.getDefault(),
Messages.ColorizerReader_ERROR_PARSING_COLOR, e);
}
try
{
rgb.green = Integer.parseInt(rgbs[1].trim());
}
catch (NumberFormatException e)
{
sendError(Messages.ColorizerReader_ERR_InvalidGreenValueForRGBColor + original + "\""); //$NON-NLS-1$
IdeLog.logError(UnifiedEditorsPlugin.getDefault(),
Messages.ColorizerReader_ERROR_PARSING_COLOR, e);
}
try
{
rgb.blue = Integer.parseInt(rgbs[2].trim());
}
catch (NumberFormatException e)
{
sendError(Messages.ColorizerReader_ERR_InvalidBlueValueForRGBColor + original + "\""); //$NON-NLS-1$
IdeLog.logError(UnifiedEditorsPlugin.getDefault(),
Messages.ColorizerReader_ERROR_PARSING_COLOR, e);
}
}
}
else if (value.startsWith("COLOR")) //$NON-NLS-1$
{
Class<?> c = SWT.class;
Field f = c.getField(value);
final int result = f.getInt(c);
final Display display = Display.getDefault();
if (display != null)
{
class ColorResult
{
Color color = null;
}
final ColorResult colorResult = new ColorResult();
display.syncExec(new Runnable()
{
public void run()
{
colorResult.color = display.getSystemColor(result);
}
});
if (colorResult.color != null)
{
rgb = colorResult.color.getRGB();
}
}
}
else
{
sendError(Messages.ColorizerReader_ERR_InvalidRGBValue + original + "\""); //$NON-NLS-1$
}
}
catch (Exception e)
{
sendError(Messages.ColorizerReader_ERR_InvalidRGBValue + original + Messages.ColorizerReader_ERR_InvalidRGBValueSuffix);
}
return rgb;
}
/**
* Groups the token of the token list
*
* @param tokenList -
* token list
*/
private void groupTokens(ITokenList tokenList)
{
categoriesToToken = new HashMap<String, Map<String, IToken>>();
if (tokenList == null)
{
return;
}
for (int i = 0; i < tokenList.size(); i++)
{
IToken curr = tokenList.get(i);
Map<String, IToken> types = null;
if (categoriesToToken.containsKey(curr.getCategory()))
{
types = categoriesToToken.get(curr.getCategory());
}
else
{
types = new HashMap<String, IToken>();
categoriesToToken.put(curr.getCategory(), types);
ColorizationStyle originalColorStyle = new ColorizationStyle();
originalColorStyle.setForegroundColor(UnifiedColorManager.getInstance().getColor(new RGB(0, 0, 0)));
originalColorStyle.setName(curr.getCategory());
CategoryColorizer catColorizer = new CategoryColorizer();
catColorizer.setName(curr.getCategory());
catColorizer.setStyle(originalColorStyle);
colorizer.addCategoryColorizer(catColorizer);
}
types.put(curr.getType(), curr);
}
}
/**
* Gets the token corresponding to the parameters
*
* @param category -
* name of category
* @param type -
* name of token
* @return - token object
*/
private IToken getToken(String category, String type)
{
if (categoriesToToken.containsKey(category))
{
Map<String, IToken> tokens = categoriesToToken.get(category);
if (tokens.containsKey(type))
{
return tokens.get(type);
}
}
return null;
}
private boolean containsCategory(String category)
{
return categoriesToToken.containsKey(category);
}
/**
* Creates the token colorizer for the parameters
*
* @param lc -
* language colorizer
* @param token -
* token to colorizer
* @param style -
* name of style
*/
private void styleToken(LanguageColorizer lc, IToken token, String style)
{
if (styles.containsKey(style))
{
ColorizationStyle originalColorStyle = styles.get(style);
ColorizationStyle newColorStyle = new ColorizationStyle(originalColorStyle);
newColorStyle.setName(token.getCategory() + "_" + token.getType()); //$NON-NLS-1$
TokenColorizer tc = lc.getTokenColorizer(token);
if (tc == null)
{
tc = new TokenColorizer();
tc.setToken(token);
lc.addTokenColorizer(tc);
}
tc.setBaseColorization(newColorStyle);
}
else
{
TokenColorizer tc = new TokenColorizer();
tc.setToken(token);
ColorizationStyle newColorStyle = new ColorizationStyle();
newColorStyle.setName(token.getCategory() + "_" + token.getType()); //$NON-NLS-1$
newColorStyle.setForegroundColor(UnifiedColorManager.getInstance().getColor(new RGB(0, 0, 0)));
tc.setBaseColorization(newColorStyle);
lc.addTokenColorizer(tc);
waitingElements.put(token, style);
}
}
private void styleCategory(LanguageColorizer lc, String category, String style)
{
if (styles.containsKey(style))
{
ColorizationStyle originalColorStyle = styles.get(style);
ColorizationStyle newColorStyle = new ColorizationStyle(originalColorStyle);
newColorStyle.setName(category);
CategoryColorizer catColorizer = new CategoryColorizer();
catColorizer.setName(category);
catColorizer.setStyle(newColorStyle);
lc.addCategoryColorizer(catColorizer);
}
else
{
waitingElements.put(category, style);
}
}
/**
* @param colorizer
* @param region
* @param style
*/
private void styleRegion(LanguageColorizer lc, IToken token, Region region, String style)
{
if (styles.containsKey(style))
{
ColorizationStyle originalColorStyle = styles.get(style);
ColorizationStyle newColorStyle = new ColorizationStyle(originalColorStyle);
newColorStyle.setName(token.getCategory() + "_" + token.getType() + "_" + region.getName()); //$NON-NLS-1$ //$NON-NLS-2$
region.setStyle(newColorStyle);
TokenColorizer tc = lc.getTokenColorizer(token);
tc.addColorization(region);
}
else
{
waitingElements.put(region, style);
}
}
/**
* Enter the colorizer element
*
* @param ns
* @param name
* @param qname
* @param attributes
*/
public void enterColorizer(String ns, String name, String qname, Attributes attributes)
{
styles.clear();
waitingElements.clear();
regionsToToken.clear();
categoriesToToken.clear();
mimeType = attributes.getValue(ColorizationConstants.LANGUAGE_ATTR);
colorizer = new LanguageColorizer(mimeType);
// Add handlers
for (int i = 0; i < handlers.size(); i++)
{
IColorizerHandler handler = handlers.get(i);
if (handler != null && mimeType.equals(handler.getLanguage()))
{
colorizer.addHandler(handler);
}
}
groupTokens(getDefaultTokenList());
String backgroundColor = attributes.getValue(ColorizationConstants.BACKGROUND_ATTR);
String selectionFgColor = attributes.getValue(ColorizationConstants.SELECTIONFOREGROUND_ATTR);
String selectionBgColor = attributes.getValue(ColorizationConstants.SELECTIONBACKGROUND_ATTR);
String caretColor = attributes.getValue(ColorizationConstants.CARETCOLOR_ATTR);
String lineHighlightColor = attributes.getValue(ColorizationConstants.LINEHIGHLIGHT_ATTR);
String foldingBgColor = attributes.getValue(ColorizationConstants.FOLDING_BACKGROUND_ATTR);
String foldingFgColor = attributes.getValue(ColorizationConstants.FOLDING_FOREGROUND_ATTR);
if (backgroundColor != null && selectionFgColor != null && selectionBgColor != null && caretColor != null
&& lineHighlightColor != null)
{
RGB bgColor = parseRGB(backgroundColor);
colorizer.setBackground(UnifiedColorManager.getInstance().getColor(bgColor));
RGB selectionFg = parseRGB(selectionFgColor);
colorizer.setSelectionForeground(UnifiedColorManager.getInstance().getColor(selectionFg));
RGB selectionBg = parseRGB(selectionBgColor);
colorizer.setSelectionBackground(UnifiedColorManager.getInstance().getColor(selectionBg));
RGB cColor = parseRGB(caretColor);
colorizer.setCaretColor(UnifiedColorManager.getInstance().getColor(cColor));
RGB lineColor = parseRGB(lineHighlightColor);
colorizer.setLineHighlightColor(UnifiedColorManager.getInstance().getColor(lineColor));
if (foldingBgColor != null && foldingFgColor != null)
{
RGB foldingFg = parseRGB(foldingFgColor);
colorizer.setFoldingFg(UnifiedColorManager.getInstance().getColor(foldingFg));
RGB foldingBg = parseRGB(foldingBgColor);
colorizer.setFoldingBg(UnifiedColorManager.getInstance().getColor(foldingBg));
}
}
}
/**
* Exit the colorizer element
*
* @param ns
* @param name
* @param qname
*/
public void exitColorizer(String ns, String name, String qname)
{
styles.clear();
if (waitingElements.isEmpty() && registerColorizer)
{
LanguageRegistry.registerLanguageColorizer(mimeType, colorizer);
}
waitingElements.clear();
regionsToToken.clear();
categoriesToToken.clear();
}
/**
* Enter the category element
*
* @param ns
* @param name
* @param qname
* @param attributes
*/
public void enterCategory(String ns, String name, String qname, Attributes attributes)
{
currentCategory = attributes.getValue(ColorizationConstants.NAME_ATTR);
String style = attributes.getValue(ColorizationConstants.STYLE_ATTR);
if (containsCategory(currentCategory))
{
styleCategory(colorizer, currentCategory, style);
}
else
{
currentCategory = null;
}
}
/**
* Exit the category element
*
* @param ns
* @param name
* @param qname
*/
public void exitCategory(String ns, String name, String qname)
{
currentCategory = null;
}
/**
* Enter the token element
*
* @param ns
* @param name
* @param qname
* @param attributes
*/
public void enterToken(String ns, String name, String qname, Attributes attributes)
{
String type = attributes.getValue(ColorizationConstants.TYPE_ATTR);
String category = currentCategory == null ? attributes.getValue(ColorizationConstants.CATEGORY_ATTR)
: currentCategory;
if (category != null)
{
String style = attributes.getValue(ColorizationConstants.STYLE_ATTR);
IToken token = getToken(category, type);
if (token != null)
{
currentToken = token;
styleToken(colorizer, token, style);
}
}
}
/**
* Exit the token element
*
* @param ns
* @param name
* @param qname
*/
public void exitToken(String ns, String name, String qname)
{
currentToken = null;
}
/**
* Enter the style element
*
* @param ns
* @param name
* @param qname
* @param attributes
*/
public void enterStyle(String ns, String name, String qname, Attributes attributes)
{
ColorizationStyle style = new ColorizationStyle();
String id = attributes.getValue(ColorizationConstants.ID_ATTR);
String fg = attributes.getValue(ColorizationConstants.FOREGROUND_ATTR);
String bg = attributes.getValue(ColorizationConstants.BACKGROUND_ATTR);
String bold = attributes.getValue(ColorizationConstants.FONTWEIGHT_ATTR);
String italic = attributes.getValue(ColorizationConstants.FONTSTYLE_ATTR);
String ul = attributes.getValue(ColorizationConstants.TEXTDECORATION_ATTR);
if (styles.containsKey(id))
{
sendWarning(Messages.ColorizerReader_WRN_IgnoringDeclarationOfDuplicateStyle + id + "\""); //$NON-NLS-1$
return;
}
style.setName(id);
RGB rgb = parseRGB(fg);
style.setForegroundColor(UnifiedColorManager.getInstance().getColor(rgb));
if (bg != null)
{
rgb = parseRGB(bg);
style.setBackgroundColor(UnifiedColorManager.getInstance().getColor(rgb));
}
if ("bold".equalsIgnoreCase(bold)) //$NON-NLS-1$
{
style.setBold(true);
}
if ("italic".equalsIgnoreCase(italic)) //$NON-NLS-1$
{
style.setItalic(true);
}
if ("underline".equalsIgnoreCase(ul)) //$NON-NLS-1$
{
style.setUnderline(true);
}
styles.put(id, style);
if (waitingElements.containsValue(id))
{
Iterator<Object> waitingList = waitingElements.keySet().iterator();
while (waitingList.hasNext())
{
Object curr = waitingList.next();
if (id.equals(waitingElements.get(curr)))
{
if (curr instanceof IToken)
{
waitingList.remove();
styleToken(colorizer, (IToken) curr, id);
}
else if (curr instanceof String)
{
waitingList.remove();
styleCategory(colorizer, (String) curr, id);
}
else if (curr instanceof Region)
{
waitingList.remove();
IToken token = regionsToToken.get(curr);
styleRegion(colorizer, token, (Region) curr, id);
}
}
}
}
}
/**
* Enter the region element
*
* @param ns
* @param name
* @param qname
* @param attributes
*/
public void enterRegion(String ns, String name, String qname, Attributes attributes)
{
String style = attributes.getValue(ColorizationConstants.STYLE_ATTR);
String offset = attributes.getValue(ColorizationConstants.OFFSET_ATTR).trim();
String length = attributes.getValue(ColorizationConstants.LENGTH_ATTR).trim();
String id = attributes.getValue(ColorizationConstants.NAME_ATTR);
int offsetInt;
int lengthInt;
boolean offsetRelative = false;
boolean lengthRelative = false;
if (currentToken != null)
{
try
{
if (offset.startsWith(ColorizationConstants.LENGTH_KEYWORD))
{
offsetInt = Integer.parseInt(offset.substring(ColorizationConstants.LENGTH_KEYWORD.length(), offset
.length()));
offsetRelative = true;
}
else
{
offsetInt = Integer.parseInt(offset);
}
}
catch (NumberFormatException e)
{
this.sendError(Messages.ColorizerReader_ERR_NFEInLengthRegion + id);
return;
}
try
{
if (length.startsWith(ColorizationConstants.LENGTH_KEYWORD))
{
lengthInt = Integer.parseInt(length.substring(ColorizationConstants.LENGTH_KEYWORD.length(), length
.length()));
lengthRelative = true;
}
else
{
lengthInt = Integer.parseInt(length);
}
Region region = new Region(offsetInt, offsetRelative, lengthInt, lengthRelative, null);
region.setLengthString(length);
region.setOffsetString(offset);
region.setName(id);
regionsToToken.put(region, currentToken);
styleRegion(colorizer, currentToken, region, style);
}
catch (NumberFormatException e)
{
this.sendError(Messages.ColorizerReader_ERR_NFEInOffsetRegion + id);
return;
}
}
}
/**
* Exit the region element
*
* @param ns
* @param name
* @param qname
*/
public void exitRegion(String ns, String name, String qname)
{
}
/**
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] buffer, int offset, int length)
{
// Does nothing, no text nodes in this xml format
}
/**
* @param language
*/
public void restoreDefault(String language)
{
URL url = urls.get(language);
String id = ids.get(language);
if (url != null && id != null)
{
loadColorizationFromURL(url, id, true);
}
}
/**
* @param language
* @param preferenceId
*/
public void setPreferenceId(String language, String preferenceId)
{
ids.put(language, preferenceId);
}
/**
* Gets the colorizer instance creator for a language
*
* @param language
* @return - instance creator
*/
public InstanceCreator getInstanceCreator(String language)
{
return instanceCreators.get(language);
}
/**
* Creates schema.
*
* @return - schema
*/
protected Schema createSchema()
{
InputStream schemaStream = ColorizerReader.class.getResourceAsStream(SCHEMA); //$NON-NLS-1$
try
{
// create the schema
Schema schema = SchemaBuilder.fromXML(schemaStream, this);
return schema;
}
catch (SchemaInitializationException e)
{
IdeLog.logError(UnifiedEditorsPlugin.getDefault(), Messages.ColorizerReader_ERROR_LOADING_SCHEMA);
}
finally
{
// close the input stream
try
{
schemaStream.close();
}
catch (IOException e)
{
}
}
return null;
}
/**
* Gets default token list. Searches in Language registry if default list is not defined.
*
* @return default token list.
*/
private ITokenList getDefaultTokenList()
{
if (defaultTokenList != null)
{
return defaultTokenList;
}
return LanguageRegistry.getTokenList(mimeType);
}
}