/**
* Copyright (c) 2011 Cloudsmith, Inc. and others.
* 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:
* Cloudsmith
*
*/
package org.cloudsmith.geppetto.pp.dsl.ui.labeling;
import java.util.List;
import org.cloudsmith.geppetto.pp.AppendExpression;
import org.cloudsmith.geppetto.pp.AtExpression;
import org.cloudsmith.geppetto.pp.Definition;
import org.cloudsmith.geppetto.pp.DoubleQuotedString;
import org.cloudsmith.geppetto.pp.Expression;
import org.cloudsmith.geppetto.pp.ExpressionTE;
import org.cloudsmith.geppetto.pp.HostClassDefinition;
import org.cloudsmith.geppetto.pp.ImportExpression;
import org.cloudsmith.geppetto.pp.LiteralList;
import org.cloudsmith.geppetto.pp.LiteralName;
import org.cloudsmith.geppetto.pp.LiteralNameOrReference;
import org.cloudsmith.geppetto.pp.NodeDefinition;
import org.cloudsmith.geppetto.pp.ParenthesisedExpression;
import org.cloudsmith.geppetto.pp.PuppetManifest;
import org.cloudsmith.geppetto.pp.ResourceBody;
import org.cloudsmith.geppetto.pp.ResourceExpression;
import org.cloudsmith.geppetto.pp.SingleQuotedString;
import org.cloudsmith.geppetto.pp.TextExpression;
import org.cloudsmith.geppetto.pp.VariableExpression;
import org.cloudsmith.geppetto.pp.VariableTE;
import org.cloudsmith.geppetto.pp.VerbatimTE;
import org.cloudsmith.geppetto.pp.adapters.ClassifierAdapter;
import org.cloudsmith.geppetto.pp.adapters.ClassifierAdapterFactory;
import org.cloudsmith.geppetto.pp.dsl.validation.PPJavaValidator;
import org.cloudsmith.geppetto.pp.pptp.Function;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.resource.ColorRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.swt.graphics.TextStyle;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider;
import org.eclipse.xtext.util.Strings;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
/**
* Provides labels for a EObjects.
*
* see http://www.eclipse.org/Xtext/documentation/latest/xtext.html#labelProvider
*/
public class PPLabelProvider extends DefaultEObjectLabelProvider implements IIconNames {
private static class DefaultStyler extends Styler {
private final String fForegroundColorName;
private final String fBackgroundColorName;
public DefaultStyler(String foregroundColorName, String backgroundColorName) {
fForegroundColorName = foregroundColorName;
fBackgroundColorName = backgroundColorName;
}
@Override
public void applyStyles(TextStyle textStyle) {
ColorRegistry colorRegistry = JFaceResources.getColorRegistry();
if(fForegroundColorName != null) {
textStyle.foreground = colorRegistry.get(fForegroundColorName);
}
if(fBackgroundColorName != null) {
textStyle.background = colorRegistry.get(fBackgroundColorName);
}
}
}
@Inject
private PPJavaValidator validator;
// public static final String UNIT = "obj16/unit_obj.gif";
/**
* Length after which a label is truncated with '...'
*/
private static final int LABEL_LIMIT = 20;
public static final Styler ERROR_STYLER = new DefaultStyler(JFacePreferences.ERROR_COLOR, null);
public static final Styler EXPR_STYLER = new DefaultStyler(JFacePreferences.QUALIFIER_COLOR, null);
@Inject
public PPLabelProvider(AdapterFactoryLabelProvider delegate) {
super(delegate);
}
private StyledString appendStyled(StyledString s, Object a) {
return appendStyled(s, a, null);
}
private StyledString appendStyled(StyledString s, Object a, Styler styler) {
if(a instanceof String)
s.append((String) a, styler);
else if(a instanceof StyledString) {
if(styler != null)
s.append(a.toString(), styler); // restyle
else
s.append((StyledString) a);
}
else
s.append(a.toString(), styler);
return s;
}
public Object image(AppendExpression o) {
return APPEND;
}
public Object image(Definition o) {
return DEFINITION;
}
public Object image(Expression o) {
if(o.eContainer() instanceof ImportExpression)
return IMPORT;
return null;
}
public Object image(Function o) {
return FUNCTION;
}
public Object image(HostClassDefinition element) {
return CLASS;
}
public Object image(ImportExpression element) {
if(element.getValues().size() <= 1)
return IMPORT;
return IMPORTS;
}
public Object image(Keyword o) {
return BLUE_CIRCLE;
}
public Object image(NodeDefinition o) {
return NODE;
}
public Object image(PuppetManifest o) {
return FILE;
}
public Object image(ResourceBody o) {
return image((ResourceExpression) o.eContainer());
}
public Object image(ResourceExpression o) {
int resourceClassifier = ClassifierAdapterFactory.eINSTANCE.adapt(o).getClassifier();
if(resourceClassifier == ClassifierAdapter.UNKNOWN)
validator.checkResourceExpression(o);
resourceClassifier = ClassifierAdapterFactory.eINSTANCE.adapt(o).getClassifier();
switch(resourceClassifier) {
case ClassifierAdapter.UNKNOWN:
return RESOURCE_UNKNOWN;
case ClassifierAdapter.RESOURCE_IS_BAD:
return RESOURCE_UNKNOWN;
case ClassifierAdapter.RESOURCE_IS_DEFAULT:
return RESOURCE_DEFAULTS;
case ClassifierAdapter.RESOURCE_IS_OVERRIDE:
return RESOURCE_OVERRIDE;
default:
return RESOURCE_REGULAR;
}
}
private StyledString literalNames(List<? extends EObject> exprs) {
StyledString result = new StyledString();
boolean first = true;
for(EObject expr : exprs) {
Object label = doGetText(expr);
if(first)
first = false;
else
result.append(", ");
if(label instanceof String)
result.append((String) label);
else if(label instanceof StyledString)
result.append((StyledString) label);
else
result.append("?");
}
// truncate long list (bad way, destroys individual styles)
if(result.length() > LABEL_LIMIT)
return new StyledString(result.getString().substring(0, LABEL_LIMIT) + "...");
return result;
}
private String nullSafeString(String s) {
return s == null
? ""
: s;
}
StyledString text(AtExpression o) {
StyledString label = new StyledString();
Object lo = doGetText(o.getLeftExpr());
appendStyled(label, lo);
label.append("[");
for(Expression expr : o.getParameters()) {
appendStyled(label, doGetText(expr));
}
label.append("]");
return label;
}
StyledString text(Definition ele) {
StyledString bld = new StyledString(ele.getClassName());
bld.append(" : Definition", StyledString.DECORATIONS_STYLER);
return bld;
}
StyledString text(DoubleQuotedString ele) {
StyledString result = new StyledString();
for(TextExpression te : ele.getStringPart()) {
if(te instanceof VerbatimTE)
appendStyled(result, nullSafeString(((VerbatimTE) te).getText()));
else if(te instanceof VariableTE)
appendStyled(result, nullSafeString(((VariableTE) te).getVarName()), EXPR_STYLER);
else if(te instanceof ExpressionTE) {
ExpressionTE exprTe = (ExpressionTE) te;
Expression expr = exprTe.getExpression();
if(expr instanceof ParenthesisedExpression)
expr = ((ParenthesisedExpression) expr).getExpr();
Object label = doGetText(expr);
if(label == null)
label = "<expr>";
String stringLabel = label.toString();
if(stringLabel.length() > LABEL_LIMIT)
stringLabel = "${" + stringLabel.substring(0, LABEL_LIMIT) + "[...]}";
else
stringLabel = "${" + stringLabel + "}";
appendStyled(result, stringLabel, EXPR_STYLER);
}
}
return result;
}
StyledString text(HostClassDefinition ele) {
StyledString bld = new StyledString(ele.getClassName());
bld.append(" : Class", StyledString.DECORATIONS_STYLER);
return bld;
}
StyledString text(ImportExpression ele) {
// StyledString label = new StyledString("import declaration" + (ele.getValues().size() >1 ? "s" : ""));
List<EObject> names = Lists.newArrayList();
names.addAll(ele.getValues());
StyledString label = new StyledString("import ");
appendStyled(label, literalNames(names), EXPR_STYLER);
return label;
}
/**
* Literal lists can be used where names can appear - i.e. something has "a list of names" as name.
*
* @param ele
* @return
*/
StyledString text(LiteralList ele) {
StyledString label = new StyledString();
label.append("[", EXPR_STYLER);
label.append(literalNames(ele.getElements()));
label.append("]", EXPR_STYLER);
return label;
}
String text(LiteralName ele) {
return ele.getValue();
}
String text(LiteralNameOrReference ele) {
return ele.getValue();
}
StyledString text(NodeDefinition ele) {
StyledString bld = literalNames(ele.getHostNames());
bld.append(" : Node", StyledString.DECORATIONS_STYLER);
return bld;
}
String text(PuppetManifest ele) {
String s = ele.eResource().getURI().lastSegment();
return Strings.isEmpty(s)
? "<unnamed>"
: URI.decode(s);
}
StyledString text(ResourceBody ele) {
StyledString label = new StyledString();
appendStyled(label, doGetText(ele.getNameExpr()));
return label;
}
StyledString text(ResourceExpression ele) {
int resourceClassifier = ClassifierAdapterFactory.eINSTANCE.adapt(ele).getClassifier();
if(resourceClassifier == ClassifierAdapter.UNKNOWN)
validator.checkResourceExpression(ele);
resourceClassifier = ClassifierAdapterFactory.eINSTANCE.adapt(ele).getClassifier();
StyledString label = new StyledString();
Object name = doGetText(ele.getResourceExpr());
appendStyled(label, name);
final EList<ResourceBody> bodyList = ele.getResourceData();
final int bodyListSize = bodyList.size();
if(resourceClassifier == ClassifierAdapter.RESOURCE_IS_REGULAR) {
// append the first named resource body, and add , ... if more than one
if(bodyList.size() >= 1) {
Object bodyLabel = doGetText(bodyList.get(0).getNameExpr());
label.append(" ");
appendStyled(label, bodyLabel, StyledString.QUALIFIER_STYLER);
if(bodyListSize > 1)
label.append(", ...", StyledString.QUALIFIER_STYLER);
}
}
StyledString typeLabel = new StyledString();
switch(resourceClassifier) {
case ClassifierAdapter.UNKNOWN:
typeLabel.append(" : ", StyledString.DECORATIONS_STYLER);
typeLabel.append("Unknown type of Resource expression", ERROR_STYLER);
break;
case ClassifierAdapter.RESOURCE_IS_BAD:
typeLabel.append(" : ", StyledString.DECORATIONS_STYLER);
typeLabel.append("Invalid Resource", ERROR_STYLER);
break;
case ClassifierAdapter.RESOURCE_IS_DEFAULT:
typeLabel.append(" : Resource Defaults", StyledString.DECORATIONS_STYLER);
break;
case ClassifierAdapter.RESOURCE_IS_OVERRIDE:
typeLabel.append(" : Resource Override", StyledString.DECORATIONS_STYLER);
break;
case ClassifierAdapter.RESOURCE_IS_REGULAR:
typeLabel.append(" : Resource" + (bodyListSize > 1
? "s"
: ""), StyledString.DECORATIONS_STYLER);
break;
}
label.append(typeLabel);
return label;
}
String text(SingleQuotedString ele) {
return ele.getText();
}
String text(VariableExpression ele) {
return ele.getVarName();
}
}