Code Search for Developers
 
 
  

ColorMapEntryParser.java from PovClipse at Krugle


Show ColorMapEntryParser.java syntax highlighted

/*
 * PovClipse - Eclipse plugin for editing and rendering Povray sceene files.
 * Copyright (C) 2006-2007  Wolfgang Moestl  wmoestl@web.de
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

package com.wm.povclipse.code.parser;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Region;

import com.wm.povclipse.LoggerProvider;
import com.wm.povclipse.PovClipseEditorPlugin;
import com.wm.povclipse.code.data.ColorData;
import com.wm.povclipse.code.data.ColorMapReplaceData;
import com.wm.povclipse.code.data.ColorReplaceData;
import com.wm.povclipse.common.Formatter;
import com.wm.povclipse.preferences.PovClipseSoundsPreferencePage;
import com.wm.povclipse.preferences.PovrayPreferenceConstants;
import com.wm.povclipse.tools.AudioPlayer;
import com.wm.povclipse.utils.StringUtils;


/**
 * <p>Parses a Povray <code>color_map</code> entry statement and returns it as a List of 
 *   <code>ColorData</code> objects.</p>
 * <p>Both, the old and the newer <code>color_map</code> syntax styles are supported.
 * 
 * @author Wolfgang M&ouml;stl
 */
public class ColorMapEntryParser {

	/**
	 * Logger instance
	 */
	private static Logger logger = LoggerProvider.getLogger(ColorMapEntryParser.class.getName());
	private static Logger soundLogger = LoggerProvider.getLogger(AudioPlayer.class.getName());
	
	private static void playSound() {
		IPreferenceStore store = PovClipseEditorPlugin.getDefault().getPreferenceStore();
		String file = store.getString(PovrayPreferenceConstants.P_SOUND_EDITOR_ERROR);
		
		if (false == PovClipseSoundsPreferencePage.SOUND_NONE.equals(file)) {
			AudioPlayer player = new AudioPlayer(file, soundLogger);
			player.start();
		}
	}
	
	private static void setValuesForNewColormap(IDocument doc, IRegion region, ColorMapReplaceData replaceData) {
		try {
			// get the line prefix
			int lineOffset = doc.getLineOffset(doc.getLineOfOffset(region.getOffset()));			
			replaceData.setStatementPrefix(doc.get(lineOffset, region.getOffset() - lineOffset));						
		} catch (BadLocationException e) {
			logger.warn("BadLocationException: " + e.getMessage());
			replaceData.setStatementPrefix("");
		}
		
		replaceData.setStatementPrefix(StringUtils.ensureOnlyWhiteSpaces(replaceData.getStatementPrefix()));
		replaceData.setMapEntryPrefix(replaceData.getStatementPrefix() + "\t");
		
		replaceData.setReplaceRegion(region);
	}
	
	public static ColorMapReplaceData parseColorMap(IDocument doc, IRegion region) {
		boolean newStatement = false;
		IRegion mapRegionOpening = null;
		IRegion mapRegionClosing = null;
		ColorMapReplaceData replaceData = new ColorMapReplaceData();

		try {
			List<ColorData> initList = new ArrayList<ColorData>();
			
			// search backwards until we find a "color_map" string
			FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(doc);
			IRegion colormapRegion = finder.find(region.getOffset()+8 > doc.getLength()-1 ? doc.getLength()-1 : region.getOffset()+8, "color_map", false, false, false, false);
													
			if (null == colormapRegion) {
				logger.trace("[color_map] not found!");
				newStatement = true;
				
				setValuesForNewColormap(doc, region, replaceData);
			} else {					
				// get the line prefix
				int lineOffset = doc.getLineOffset(doc.getLineOfOffset(colormapRegion.getOffset()));
				
				replaceData.setStatementPrefix(doc.get(lineOffset, colormapRegion.getOffset() - lineOffset));
				replaceData.setStatementPrefix(StringUtils.ensureOnlyWhiteSpaces(replaceData.getStatementPrefix()));
				
				mapRegionOpening = finder.find(colormapRegion.getOffset(), "{", true, false, false, false);
				mapRegionClosing = finder.find(colormapRegion.getOffset(), "}", true, false, false, false);
				
				if (mapRegionOpening == null) {
					logger.debug("[{] not found!");
					playSound();
					return null;
				}
				if (mapRegionClosing  == null) {
					logger.debug("[}] not found!");
					playSound();
					return null;
				}
				
				replaceData.setReplaceRegion(new Region(colormapRegion.getOffset(), mapRegionClosing.getOffset() - colormapRegion.getOffset()));
				
				logger.debug("act pos: " + region.getOffset() + "; [color_map]=" + colormapRegion.getOffset() + ", [{]=" + mapRegionOpening.getOffset() + ", [}]=" + mapRegionClosing.getOffset());
				
				if (mapRegionClosing.getOffset() < region.getOffset()) {
					logger.debug("[}] BEFOR actual position!");
					newStatement = true;
					setValuesForNewColormap(doc, region, replaceData);
				}
				if (colormapRegion.getOffset() > region.getOffset()) {
					logger.debug("[color_map] AFTER actual position!");
					newStatement = true;
					setValuesForNewColormap(doc, region, replaceData);
				}
				
				if (!newStatement) {
					List braces = splitBrackets(doc, finder, mapRegionOpening.getOffset(), mapRegionClosing.getOffset());
					
					HashMap<String, Integer> prefixMap = new HashMap<String, Integer>();
					for (int i=0; i<braces.size(); i++) {
						IRegion braceRegion = (IRegion)braces.get(i);	
						
						// get the line prefix
						lineOffset = doc.getLineOffset(doc.getLineOfOffset(braceRegion.getOffset()));
						
						String prefix = doc.get(lineOffset, braceRegion.getOffset()-lineOffset);
						if (StringUtils.containsOnlySpaces(prefix)) {
							Integer counter = (Integer)prefixMap.get(prefix);
							if (null == counter) 
								prefixMap.put(prefix, new Integer(1));
							else
								prefixMap.put(prefix, new Integer(counter.intValue() + 1));
						}
						
						List<ColorData> colorList = ColorMapEntryParser.parseColorList(doc, braceRegion);
						// avoide dulicate entries
						for (int j=0; j<colorList.size(); j++) {
							ColorData obj = (ColorData)colorList.get(j);
							if (!initList.contains(obj))
								initList.add(obj);
						}
						
						replaceData.setColorList(initList);
					}
					
					
					Iterator it = prefixMap.keySet().iterator();
					int max = -1;
					while (it.hasNext()) {
						String key = (String)it.next();
						Integer val = (Integer)prefixMap.get(key);
						if (val.intValue() > max)
							replaceData.setMapEntryPrefix(key);
					}						
				}
			}
			
			replaceData.setNewStatement(newStatement);
			replaceData.setMapEntryPrefix(ensureLinePrefixValue(replaceData.getMapEntryPrefix()));
			
			logger.trace("Entry prefix: [" + replaceData.getMapEntryPrefix() + "]");
			
			return replaceData;
		} catch (BadLocationException e) {
			logger.warn("BadLocationException: " + e.getMessage());
			return null;
		}
	}
	
	private static String ensureLinePrefixValue(String linePrefix) {
		return (null == linePrefix) ? "\t\t\t" : linePrefix;
	}
	
	/**
	 * Parses a Povray <code>color_map entry</code> statement extracted from the document and returns
	 * it as a <code>ColorData</code> object.<br>
	 * The entry is everything between a [] bracket pair.
	 * @param doc The document being used for extracting the <code>color_map entry</code> statement.
	 * @param region The <code>IRegion</code> within the document containing the <code>color_map entry</code> statement.
	 * @return A List of <code>ColorData</code> object(s) representing the <code>color_map entry</code> statement or
	 * an <code>EMPTY</code> List if the statement can not be parsed. Never <code>NULL</code>.
	 */
	public static List<ColorData> parseColorList(IDocument doc, IRegion region) {
		List<ColorData> retList = new ArrayList<ColorData>();
		
		ColorData colorData;
				
		try {
			FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(doc);		
		
			IRegion colorRegionOne = finder.find(region.getOffset(), "rgb", true, false, false, false);
			if (null == colorRegionOne) return retList;
			// ensure we're within our allowed region
			if (colorRegionOne.getOffset() >= region.getOffset() + region.getLength()) return retList;
			
			IRegion colorRegionTwo = finder.find(colorRegionOne.getOffset() + 3, "rgb", true, false, false, false);
			if (null != colorRegionTwo && colorRegionTwo.getOffset() >= region.getOffset() + region.getLength())
				colorRegionTwo = null; // restrict to allowed region
			
			IRegion parseColorRegion;
			if (null == colorRegionTwo) {
				// no second statement present
				parseColorRegion = new Region(colorRegionOne.getOffset()-2, 2+region.getOffset() + region.getLength() - colorRegionOne.getOffset());
			} else {
				// second statement IS present
				parseColorRegion = new Region(colorRegionOne.getOffset()-2, 2+colorRegionTwo.getOffset() - colorRegionOne.getOffset());				
			}
			
			// try the first color statement
			ColorReplaceData repaceData = ColorParser.parse(doc, parseColorRegion, true);		
			if (repaceData != null) {
				colorData = repaceData.getColorData();
				try {
					String number = StringUtils.extractUSNumber(doc.get(region.getOffset(), colorRegionOne.getOffset() - region.getOffset()), 1);
					colorData.setPosition(Formatter.floatFormatter.parse(number).floatValue());													
				} catch (ParseException e) {
					// set a default value
					colorData.setPosition(0.0f);
				}
				logger.debug("Adding color_map entry " + colorData.toString());
				retList.add(colorData);				
			}
			if (null != colorRegionTwo) {
				// try the second color statement
				parseColorRegion = new Region(colorRegionTwo.getOffset(), region.getOffset() + region.getLength() - colorRegionTwo.getOffset());				
				repaceData = ColorParser.parse(doc, parseColorRegion, true);
				if (repaceData != null) {
					colorData = repaceData.getColorData();
					try {
						String number = StringUtils.extractUSNumber(doc.get(region.getOffset(), colorRegionOne.getOffset() - region.getOffset()), 2);
						colorData.setPosition(Formatter.floatFormatter.parse(number).floatValue());													
					} catch (ParseException e) {
						// set a default value
						colorData.setPosition(0.0f);
					}
					logger.trace("Adding color_map entry " + colorData.toString());
					retList.add(colorData);				
				}
			}
		} catch (BadLocationException e) {
			logger.warn("BadLocationException: " + e.getMessage());
			return null;
		}
		return retList;
	}
		
	/** 
	 * Finds &quot;[]&quot; pairs and returns them as List of <code>IRegion</code> objects.
	 * @param doc Teh document to process
	 * @param finder The <code>FindReplaceDocumentAdapter</code> to be used.
	 * @param offsetOpeningBrace The offset to start with
	 * @param offsetClosingBrace The offset to end with.
	 * @return A list of <code>IRegion</code> objects
	 */
	private static List<Region> splitBrackets(IDocument doc, FindReplaceDocumentAdapter finder, int offsetOpeningBrace, int offsetClosingBrace) {
		ArrayList<Region> lst = new ArrayList<Region>();
		boolean found = true;
		int startOffset = offsetOpeningBrace;
		while (found) {
			try {
				IRegion matchStart = finder.find(startOffset, "[", true, true, false, false);
				IRegion matchEnd = finder.find(startOffset, "]", true, true, false, false);
				found = (matchStart != null && matchEnd != null) ;
				if (found && (matchEnd.getOffset() < offsetClosingBrace)) {
					lst.add(new Region(matchStart.getOffset(), matchEnd.getOffset() - matchStart.getOffset()));
					startOffset = matchEnd.getOffset()+1;
					logger.trace("found: " + matchStart.getOffset() + " - " + matchEnd.getOffset());
				} else
					found = false;
			} catch (BadLocationException e) {
				found = false;
			}
		}
		return lst;
	}
}




See more files for this project here

PovClipse

PovClipse is an eclipse editor plugin for Povray (Persistence of Vision Raytracer) sceene- and include files.\r\nIt features syntax highlighting, code folding, code assist, outline view as well as running Povray using render configurations.

Project homepage: http://sourceforge.net/projects/povclipse
Programming language(s): Java
License: other

  ColorMapEntryParser.java
  ColorParser.java