/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* 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
*
* Contributors:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.editors.all;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Currency;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.ui.editors.text.FileDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.MarkerUtilities;
import de.innovationgate.eclipse.editors.helpers.MarkingHandler;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.wga.model.VersionCompliance;
public class InvalidEncodingMarkingHandler implements MarkingHandler {
public static final String MARKER_ID = "de.innovationgate.eclipse.ids.markers.encoding.InvalidCharacter";
private IDocumentProvider _provider;
private static Set<Character> CURRENCY_SYMBOLS = new HashSet<Character>();
static {
Iterator<Locale> locs = Arrays.asList(Locale.getAvailableLocales()).iterator();
while (locs.hasNext()) {
try {
Locale loc = locs.next();
String symbol = Currency.getInstance(loc).getSymbol();
if (symbol.length() == 1) {
CURRENCY_SYMBOLS.add(symbol.charAt(0));
}
}
catch (RuntimeException e) {
}
}
}
public static final String ALLOWED_NONALPHANUMERIC = "=<>(){}[].,/\\|&%$�\"!?+-*~#':;-_�`@^";
public InvalidEncodingMarkingHandler() {
}
public void createMarkers(IFile file, IDocument document) throws CoreException {
file.deleteMarkers(MARKER_ID, true, IResource.DEPTH_ZERO);
if (_provider != null && _provider instanceof FileDocumentProvider) {
String encoding = file.getCharset(true);
LineNumberReader read = null;
try {
read = new LineNumberReader(new InputStreamReader(new FileInputStream(file.getLocation().toFile()), encoding));
String line;
while ((line = read.readLine()) != null) {
boolean invalidCharsFound = false;
Map<String,Object> attributes = new HashMap<String, Object>();
List<Character> invalidCharsInLine = new ArrayList<Character>();
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (!Character.isLetterOrDigit(c) &&
!Character.isWhitespace(c) &&
!CURRENCY_SYMBOLS.contains(c) &&
ALLOWED_NONALPHANUMERIC.indexOf(c) == -1) {
invalidCharsFound = true;
invalidCharsInLine.add(c);
}
}
if (invalidCharsFound) {
// create marker
try {
IRegion lineInfo = document.getLineInformation(read.getLineNumber() - 1);
String lineContent = document.get(lineInfo.getOffset(), lineInfo.getLength());
int beginningSpaces = 0;
for (int i = 0; i < lineContent.length(); i++) {
char c = lineContent.charAt(i);
if (Character.isWhitespace(c)) {
beginningSpaces++;
} else {
break;
}
}
int trailingSpaces = 0;
for (int i = lineContent.length() - 1; i >= 0; i--) {
char c = lineContent.charAt(i);
if (Character.isWhitespace(c)) {
trailingSpaces++;
} else {
break;
}
}
int charStart = lineInfo.getOffset() + beginningSpaces;
int charEnd = charStart + lineInfo.getLength() - beginningSpaces - trailingSpaces;
Map<String,Object> map = new HashMap<String,Object>();
MarkerUtilities.setLineNumber(map, read.getLineNumber()-1);
MarkerUtilities.setCharStart(map, charStart);
MarkerUtilities.setCharEnd(map, charEnd);
MarkerUtilities.setMessage(map, "Invalid characters found '" + WGUtils.serializeCollection(invalidCharsInLine, ",") + "' .");
map.put(IMarker.LOCATION, file.getFullPath().toString());
map.put(IMarker.SEVERITY, new Integer(IMarker.SEVERITY_ERROR));
if (attributes != null) {
map.putAll(attributes);
}
MarkerUtilities.createMarker(file, map, MARKER_ID);
} catch (BadLocationException e) {
}
}
}
} catch (UnsupportedEncodingException e) {
} catch (IOException e) {
} finally {
if (read != null) {
try {
read.close();
} catch (IOException e) {
}
}
}
}
}
public void setWGAVersionCompliance(VersionCompliance versionCompliance) {
}
public void setDocumentProvider(IDocumentProvider provider) {
_provider = provider;
}
public static boolean containsInvalidChar(String input) {
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (!Character.isLetterOrDigit(c) &&
!Character.isWhitespace(c) &&
!CURRENCY_SYMBOLS.contains(c) &&
ALLOWED_NONALPHANUMERIC.indexOf(c) == -1) {
return true;
}
}
return false;
}
public void createMarkers(IResource resource) throws CoreException {
}
}