/** * Copyright (c) 2006-2012 Cloudsmith Inc. and other contributors, as listed below. * 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.xtext.dommodel.formatter.css; import java.util.Set; import org.cloudsmith.xtext.dommodel.IDomNode; import org.cloudsmith.xtext.dommodel.IDomNode.NodeType; import org.cloudsmith.xtext.dommodel.formatter.ILayoutManager; import com.google.common.base.Function; import com.google.inject.Inject; import com.google.inject.Singleton; /** * An IStyleFacory implementation for Xtext IDomNode */ @Singleton public class StyleFactory implements IStyleFactory { protected static abstract class AbstractStyle<T> implements IStyle<T> { private Function<IDomNode, T> function; private Set<NodeType> types; private T value; public AbstractStyle(Function<IDomNode, T> function) { this.function = function; } public AbstractStyle(T value) { this.value = value; } @Override public T getValue(IDomNode ge) { return function != null ? function.apply(ge) : value; } @Override public boolean isFunction() { return function != null; } protected void setTypes(Set<NodeType> types) { this.types = types; } @Override public boolean supports(NodeType type) { return types == null ? true : types.contains(type); } @Override public boolean supports(Set<NodeType> types) { return types == null ? true : this.types.containsAll(types); } } public static class AlignedSeparatorIndex extends IntegerStyle { public AlignedSeparatorIndex(Function<IDomNode, Integer> f) { super(f); } public AlignedSeparatorIndex(Integer count) { super(count); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.indent(getValue(ge)); } } public static class AlignmentStyle extends AbstractStyle<Alignment> { public AlignmentStyle(Alignment align) { super(align); setTypes(NodeType.nonWhitespaceSet); } public AlignmentStyle(Function<IDomNode, Alignment> f) { super(f); setTypes(NodeType.nonWhitespaceSet); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.align(getValue(ge)); } } public abstract static class BooleanStyle extends AbstractStyle<Boolean> { public BooleanStyle(Boolean value) { super(value); } public BooleanStyle(Function<IDomNode, Boolean> value) { super(value); } } public static class DedentStyle extends IntegerStyle { public DedentStyle(Function<IDomNode, Integer> f) { super(f); } public DedentStyle(Integer spacing) { super(spacing); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.dedent(getValue(ge)); } } protected abstract static class DoubleStyle extends AbstractStyle<Double> { public DoubleStyle(Double value) { super(value); } public DoubleStyle(Function<IDomNode, Double> value) { super(value); } } public static class IndentStyle extends IntegerStyle { public IndentStyle(Function<IDomNode, Integer> f) { super(f); } public IndentStyle(Integer count) { super(count); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.indent(getValue(ge)); } } protected abstract static class IntegerStyle extends AbstractStyle<Integer> { public IntegerStyle(Function<IDomNode, Integer> value) { super(value); } public IntegerStyle(Integer value) { super(value); } } public static class LayoutManagerStyle extends AbstractStyle<ILayoutManager> { public LayoutManagerStyle(Function<IDomNode, ILayoutManager> f) { super(f); } public LayoutManagerStyle(ILayoutManager layout) { super(layout); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.layout(getValue(ge)); } } public static class LineBreakStyle extends AbstractStyle<LineBreaks> { public LineBreakStyle(Function<IDomNode, LineBreaks> f) { super(f); setTypes(NodeType.whitespaceSet); } public LineBreakStyle(LineBreaks lineBreaks) { super(lineBreaks); setTypes(NodeType.whitespaceSet); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.lineBreaks(getValue(ge)); } } public static class SpacingStyle extends AbstractStyle<Spacing> { public SpacingStyle(Function<IDomNode, Spacing> f) { super(f); setTypes(NodeType.whitespaceSet); } public SpacingStyle(Spacing spacing) { super(spacing); setTypes(NodeType.whitespaceSet); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.spacing(getValue(ge)); } } protected abstract static class StringStyle extends AbstractStyle<String> { public StringStyle(Function<IDomNode, String> value) { super(value); } public StringStyle(String value) { super(value); } } public static class StyleNameStyle extends StringStyle { public StyleNameStyle(Function<IDomNode, String> f) { super(f); } public StyleNameStyle(String name) { super(name); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.styleName(getValue(ge)); } } public static class TokenTextStyle extends StringStyle { public TokenTextStyle(Function<IDomNode, String> f) { super(f); } public TokenTextStyle(String spacing) { super(spacing); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.tokenText(getValue(ge)); } } public static class VerbatimStyle extends BooleanStyle { public VerbatimStyle(Boolean value) { super(value); } public VerbatimStyle(Function<IDomNode, Boolean> f) { super(f); } @Override public void visit(IDomNode node, IStyleVisitor visitor) { visitor.verbatim(getValue(node)); } } public static class WidthStyle extends IntegerStyle { public WidthStyle(Function<IDomNode, Integer> f) { super(f); } public WidthStyle(Integer width) { super(width); } @Override public void visit(IDomNode ge, IStyleVisitor visitor) { visitor.width(getValue(ge)); } } private static final SpacingStyle ONESPACE = new SpacingStyle(new Spacing(1, true)); private static final SpacingStyle ONE_NON_WRAPPABLE_SPACE = new SpacingStyle(new Spacing(1, false)); private static final SpacingStyle NOSPACE_UNLESS_WRAPPED = new SpacingStyle(new Spacing(0, true)); private static final SpacingStyle NOSPACE = new SpacingStyle(new Spacing(0, false)); private static final LineBreakStyle NOLINE = new LineBreakStyle(new LineBreaks(0)); private static final LineBreakStyle ONELINE = new LineBreakStyle(new LineBreaks(1)); @Inject public StyleFactory() { } @Override public AlignmentStyle align(Alignment x) { return new AlignmentStyle(x); } @Override public AlignmentStyle align(Function<IDomNode, Alignment> f) { return new AlignmentStyle(f); } @Override public DedentStyle dedent() { return new DedentStyle(1); } @Override public DedentStyle dedent(Function<IDomNode, Integer> f) { return new DedentStyle(f); } @Override public DedentStyle dedent(Integer i) { return new DedentStyle(i); } @Override public IndentStyle indent() { return new IndentStyle(1); } @Override public IndentStyle indent(Function<IDomNode, Integer> f) { return new IndentStyle(f); } @Override public IndentStyle indent(Integer i) { return new IndentStyle(i); } @Override public LayoutManagerStyle layout(Function<IDomNode, ILayoutManager> f) { return new LayoutManagerStyle(f); } @Override public LayoutManagerStyle layout(ILayoutManager manager) { return new LayoutManagerStyle(manager); } @Override public LineBreakStyle lineBreaks(Function<IDomNode, LineBreaks> f) { return new LineBreakStyle(f); } @Override public LineBreakStyle lineBreaks(int min, int normal, int max) { return new LineBreakStyle(new LineBreaks(min, normal, max)); } @Override public LineBreakStyle lineBreaks(int min, int normal, int max, boolean acceptCommentEndingWithBreak, boolean acceptExisting) { return new LineBreakStyle(new LineBreaks(min, normal, max, acceptCommentEndingWithBreak, acceptExisting)); } @Override public LineBreakStyle noLineBreak() { return NOLINE; } @Override public SpacingStyle noSpace() { return NOSPACE; } @Override public SpacingStyle noSpaceUnlessWrapped() { return NOSPACE_UNLESS_WRAPPED; } @Override public LineBreakStyle oneLineBreak() { return ONELINE; } @Override public SpacingStyle oneNonWrappableSpace() { return ONE_NON_WRAPPABLE_SPACE; } @Override public SpacingStyle oneSpace() { return ONESPACE; } @Override public IndentStyle separatorAlignmentIndex(Function<IDomNode, Integer> f) { return new IndentStyle(f); } @Override public IndentStyle separatorAlignmentIndex(Integer i) { return new IndentStyle(i); } @Override public SpacingStyle spacing(Function<IDomNode, Spacing> f) { return new SpacingStyle(f); } @Override public SpacingStyle spacing(int min, int normal, int max) { return new SpacingStyle(new Spacing(min, normal, max)); } @Override public StyleNameStyle styleName(Function<IDomNode, String> f) { return new StyleNameStyle(f); } @Override public StyleNameStyle styleName(String s) { return new StyleNameStyle(s); } @Override public TokenTextStyle tokenText(Function<IDomNode, String> f) { return new TokenTextStyle(f); } @Override public TokenTextStyle tokenText(String s) { return new TokenTextStyle(s); } @Override public VerbatimStyle verbatim(boolean b) { return new VerbatimStyle(b); } @Override public VerbatimStyle verbatim(Function<IDomNode, Boolean> f) { return new VerbatimStyle(f); } @Override public WidthStyle width(Function<IDomNode, Integer> f) { return new WidthStyle(f); } @Override public WidthStyle width(Integer i) { return new WidthStyle(i); } }