/*******************************************************************************
* 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.tml.markers;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import de.innovationgate.eclipse.editors.ResourceIDs;
import de.innovationgate.eclipse.editors.config.TMLTag;
import de.innovationgate.eclipse.editors.helpers.MarkerFactory;
import de.innovationgate.eclipse.editors.helpers.TMLTagValidator;
import de.innovationgate.eclipse.editors.tml.TMLRegion;
import de.innovationgate.eclipse.utils.wga.WGADesignStructureHelper;
import de.innovationgate.wga.model.VersionCompliance;
public class ReferenceValidator extends TMLTagValidator {
public static final String ATTRIBUTE_REFERENCE_TYPE = "referenceType";
public static final String ATTRIBUTE_MISSING_REFERENCE_PATH = "missingReferencePath";
public static final String ATTRIBUTE_IS_PORTLET_REFERENCE = "isPortletReference";
public static final String REFERENCE_TYPE_TML = "tml";
public static final String REFERENCE_TYPE_SCRIPT = "script";
public String getMarkerID() {
return ResourceIDs.MARKER_TML_REFERENCES;
}
public void validateAndMark(IFile file, IDocument document, ITypedRegion partition, TMLRegion tmlInfo, TMLTag tag) {
int charStart = partition.getOffset();
int charEnd = charStart + partition.getLength();
if(tag.getName().equals("include") || tag.getName().equals("portlet")) {
if (!tmlInfo.hasAttribute("designdb") && !tmlInfo.isDynamicAttributeValue("ref") && !tmlInfo.isDynamicAttributeValue("medium") && !tmlInfo.hasAttribute("type", "url")) {
if(tmlInfo.getAttributeValue("ref")!=null && !tmlInfo.getAttributeValue("ref").equals("")){
charStart = partition.getOffset() + tmlInfo.getContent().indexOf("ref")+"ref='".length();
charEnd = charStart + tmlInfo.getAttributeValue("ref").length();
}
if (tmlInfo.hasAttribute("ref")) {
String ref = tmlInfo.getAttributeValue("ref");
IFile referencedFile = WGADesignStructureHelper.findReferencedTMLModule(file, ref, tmlInfo.getAttributeValue("medium"));
if (referencedFile == null) {
String referencePath = new WGADesignStructureHelper(file).computeTMLModuleReferencePath(file, ref, tmlInfo.getAttributeValue("medium"));
Map<String, Object> attributes = new HashMap<String, Object>();
if (ref != null && !ref.trim().equals("")) {
if (wgaVersionIsAtLeast(5, 4) && ref.startsWith("::") && ref.toLowerCase().endsWith("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Illegal reference '" + tmlInfo.getAttributeValue("ref") + "'.", attributes);
return;
} else {
attributes.put(ATTRIBUTE_REFERENCE_TYPE, REFERENCE_TYPE_TML);
attributes.put(ATTRIBUTE_MISSING_REFERENCE_PATH, referencePath);
if (tmlInfo.getTagName().equals("portlet") || (tmlInfo.getTagName().equals("include") && tmlInfo.hasAttribute("type", "portlet"))) {
attributes.put(ATTRIBUTE_IS_PORTLET_REFERENCE, true);
} else {
attributes.put(ATTRIBUTE_IS_PORTLET_REFERENCE, false);
}
}
}
if (wgaVersionIsAtLeast(5, 4)) {
if (!referencePath.contains("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + tmlInfo.getAttributeValue("ref") + "'.", attributes);
}
} else {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + tmlInfo.getAttributeValue("ref") + "'.", attributes);
}
}
}
}
}
// validate short tml module include syntax <tml:[modulename]>
if (wgaVersionIsAtLeast(4, 1) && tmlInfo.getTagName().matches("\\[.*\\]") && !tmlInfo.getTagName().contains("/")) {
if (!tmlInfo.hasAttribute("designdb") && !tmlInfo.isDynamicAttributeValue("medium")) {
charStart = partition.getOffset() + tmlInfo.getContent().indexOf(tmlInfo.getTagName()) + 1;
charEnd = charStart + tmlInfo.getTagName().length() - 2;
String ref = tmlInfo.getTagName().replaceAll("\\[", "");
ref = ref.replaceAll("\\]", "");
IFile referencedFile = WGADesignStructureHelper.findReferencedTMLModule(file, ref, tmlInfo.getAttributeValue("medium"));
if (referencedFile == null) {
String referencePath = new WGADesignStructureHelper(file).computeTMLModuleReferencePath(file, ref, tmlInfo.getAttributeValue("medium"));
Map<String, Object> attributes = new HashMap<String, Object>();
if (ref != null && !ref.trim().equals("")) {
if (wgaVersionIsAtLeast(5, 4) && ref.startsWith("::") && ref.toLowerCase().endsWith("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Illegal reference '" + ref + "'.", attributes);
return;
}
attributes.put(ATTRIBUTE_REFERENCE_TYPE, REFERENCE_TYPE_TML);
attributes.put(ATTRIBUTE_MISSING_REFERENCE_PATH, referencePath);
attributes.put(ATTRIBUTE_IS_PORTLET_REFERENCE, false);
}
if (wgaVersionIsAtLeast(5, 4)) {
if (!referencePath.contains("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + ref + "'.", attributes);
}
} else {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + ref + "'.", attributes);
}
}
}
}
if (tag.getName().equals("url")) {
if (!tmlInfo.hasAttribute("db") && tmlInfo.hasAttribute("type") && !tmlInfo.isDynamicAttributeValue("type") && tmlInfo.hasAttribute("name") && !tmlInfo.isDynamicAttributeValue("name")) {
handleURLNameReference(file, partition, tmlInfo);
} else if (!tmlInfo.hasAttribute("db") && !tmlInfo.isDynamicAttributeValue("layout") && !tmlInfo.isDynamicAttributeValue("medium") &&
tmlInfo.getAttributeValue("layout")!=null && !tmlInfo.getAttributeValue("layout").equals("default") && !tmlInfo.getAttributeValue("layout").equals("")) {
handleURLLayoutReference(file, partition, tmlInfo);
} else if (!tmlInfo.hasAttribute("db") && tmlInfo.hasAttribute("action") && !tmlInfo.isDynamicAttributeValue("action") && wgaVersionIsAtLeast(4, 0)) {
handleActionReference(file, partition, tmlInfo, "action");
}
} else if (tmlInfo.getTagName().equals("input") && tmlInfo.hasAttribute("changeaction") && !tmlInfo.isDynamicAttributeValue("changeaction") && wgaVersionIsAtLeast(4, 0)) {
handleActionReference(file, partition, tmlInfo, "changeaction");
} else if (tmlInfo.getTagName().equals("action") && tmlInfo.hasAttribute("ref") && !tmlInfo.isDynamicAttributeValue("ref") && wgaVersionIsAtLeast(4, 0)) {
handleActionReference(file, partition, tmlInfo, "ref");
} else if (tmlInfo.getTagName().equals("form") && tmlInfo.hasAttribute("defaultaction") && !tmlInfo.isDynamicAttributeValue("defaultaction") && wgaVersionIsAtLeast(4, 0)) {
handleActionReference(file, partition, tmlInfo, "defaultaction");
} else if (tmlInfo.getTagName().equals("button") && tmlInfo.hasAttribute("clickaction") && !tmlInfo.isDynamicAttributeValue("clickaction")) {
handleActionReference(file, partition, tmlInfo, "clickaction");
}
}
private void handleActionReference(IFile file, ITypedRegion partition, TMLRegion tmlInfo, String attributeName) {
int charStart = partition.getOffset();
int charEnd = charStart + partition.getLength();
String ref = tmlInfo.getAttributeValue(attributeName);
if (ref != null && ref.contains(":")) {
IFile referencedFile = null;
String referenceType = null;
String referencePath = null;
referencedFile = WGADesignStructureHelper.findReferencedScript(file, ref, WGADesignStructureHelper.SCRIPT_TYPE_TMLSCRIPT);
referenceType = REFERENCE_TYPE_SCRIPT;
referencePath = WGADesignStructureHelper.computeScriptReferencePath(file, ref, WGADesignStructureHelper.SCRIPT_TYPE_TMLSCRIPT);
if (referencedFile == null && referenceType != null) {
IRegion region;
try {
region = tmlInfo.getAttributeValueRegion(attributeName);
if (region != null) {
charStart = region.getOffset();
charEnd = charStart + region.getLength();
}
} catch (BadLocationException e) {
}
Map<String, Object> attributes = new HashMap<String, Object>();
if (ref != null && !ref.trim().equals("")) {
attributes.put(ATTRIBUTE_REFERENCE_TYPE, referenceType);
attributes.put(ATTRIBUTE_MISSING_REFERENCE_PATH, referencePath);
}
if (wgaVersionIsAtLeast(5, 4)) {
if (!referencePath.contains("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + ref + "'.", attributes);
}
} else {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + ref + "'.", attributes);
}
}
}
}
private void handleURLLayoutReference(IFile file, ITypedRegion partition, TMLRegion tmlInfo) {
int charStart = partition.getOffset() + tmlInfo.getContent().indexOf("layout")+"layout='".length();
int charEnd = charStart + tmlInfo.getAttributeValue("layout").length();
String ref = tmlInfo.getAttributeValue("layout");
IFile referencedFile = WGADesignStructureHelper.findReferencedTMLModule(file, ref, tmlInfo.getAttributeValue("medium"));
if (referencedFile == null) {
String referencePath = new WGADesignStructureHelper(file).computeTMLModuleReferencePath(file, ref, tmlInfo.getAttributeValue("medium"));
Map<String, Object> attributes = new HashMap<String, Object>();
if (ref != null && !ref.trim().equals("")) {
if (wgaVersionIsAtLeast(5, 4) && ref.startsWith("::") && ref.toLowerCase().endsWith("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Illegal reference '" + tmlInfo.getAttributeValue("layout") + "'.", attributes);
return;
}
attributes.put(ATTRIBUTE_REFERENCE_TYPE, REFERENCE_TYPE_TML);
attributes.put(ATTRIBUTE_MISSING_REFERENCE_PATH, referencePath);
}
if (wgaVersionIsAtLeast(5, 4)) {
if (!referencePath.contains("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + tmlInfo.getAttributeValue("layout") + "'.", attributes);
}
} else {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + tmlInfo.getAttributeValue("layout") + "'.", attributes);
}
}
}
private void handleURLNameReference(IFile file, ITypedRegion partition, TMLRegion tmlInfo) {
int charStart = partition.getOffset();
int charEnd = charStart + partition.getLength();
String type = tmlInfo.getAttributeValue("type");
if ( type != null ) {
String ref = tmlInfo.getAttributeValue("name");
IFile referencedFile = null;
String referenceType = null;
String referencePath = null;
if (type.equals(WGADesignStructureHelper.SCRIPT_TYPE_CSS) || type.equals(WGADesignStructureHelper.SCRIPT_TYPE_JS)) {
referencedFile = WGADesignStructureHelper.findReferencedScript(file, ref, type);
referenceType = REFERENCE_TYPE_SCRIPT;
referencePath = WGADesignStructureHelper.computeScriptReferencePath(file, ref, type);
} else if (type.equals("tml") && !tmlInfo.isDynamicAttributeValue("medium")) {
String medium = tmlInfo.getAttributeValue("medium");
referencedFile = WGADesignStructureHelper.findReferencedTMLModule(file, ref, medium);
referenceType = REFERENCE_TYPE_TML;
referencePath = new WGADesignStructureHelper(file).computeTMLModuleReferencePath(file, ref, medium);
}
if (referencedFile == null && referenceType != null) {
IRegion region;
try {
region = tmlInfo.getAttributeValueRegion("name");
if (region != null) {
charStart = region.getOffset();
charEnd = charStart + region.getLength();
}
} catch (BadLocationException e) {
}
Map<String, Object> attributes = new HashMap<String, Object>();
if (ref != null && !ref.trim().equals("")) {
if (wgaVersionIsAtLeast(5, 4) && ref.startsWith("::") && ref.toLowerCase().endsWith("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Illegal reference '" + ref + "'.", attributes);
return;
}
attributes.put(ATTRIBUTE_REFERENCE_TYPE, referenceType);
attributes.put(ATTRIBUTE_MISSING_REFERENCE_PATH, referencePath);
}
if (wgaVersionIsAtLeast(5, 4)) {
if (!referencePath.contains("@base")) {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + ref + "'.", attributes);
}
} else {
MarkerFactory.createErrorMarker(getMarkerID(), file, charStart, charEnd, "Unsatisfied reference '" + ref + "'.", attributes);
}
}
}
}
}