/******************************************************************************* * Copyright (c) 2008, 2013 Angelo Zerr 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: * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation *******************************************************************************/ package org.eclipse.e4.ui.css.core.serializers; import java.io.IOException; import java.io.Writer; import java.util.HashMap; import java.util.Map; import org.eclipse.e4.ui.css.core.engine.CSSEngine; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.w3c.dom.css.CSSStyleDeclaration; /** * CSS Serializer to retrieve default CSSStyleDeclaration of the SWT Widgets. */ public class CSSSerializer { public CSSSerializer() { } /** * Build CSS Style Sheet content of the <code>element</code> Object by * using {@link CSSEngine} engine configuration. The serialization result is * stored into the <code>writer</code>. If * <code>serializeChildNodes</code> is true, the method will serialize too * the child nodes of the <code>element</code>. * * @param writer * @param engine * @param element * @param serializeChildNodes * @throws IOException */ public void serialize(Writer writer, CSSEngine engine, Object element, boolean serializeChildNodes) throws IOException { serialize(writer, engine, element, serializeChildNodes, null); } /** * Build CSS Style Sheet content of the <code>element</code> Object by * using {@link CSSEngine} engine configuration. The serialization result is * stored into the <code>writer</code>. If * <code>serializeChildNodes</code> is true, the method will serialize too * the child nodes of the <code>element</code>. The * {@link CSSSerializerConfiguration} <code>configuration</code> is used * to generate selector with condition like Text[style='SWT.MULTI']. * * @param writer * @param engine * @param element * @param serializeChildNodes * @param configuration * @throws IOException */ public void serialize(Writer writer, CSSEngine engine, Object element, boolean serializeChildNodes, CSSSerializerConfiguration configuration) throws IOException { Map<String, CSSStyleDeclaration> selectors = new HashMap<>(); serialize(writer, engine, element, serializeChildNodes, selectors, configuration); boolean firstSelector = true; for (Map.Entry<String, CSSStyleDeclaration> entry : selectors.entrySet()) { String selectorName = entry.getKey(); CSSStyleDeclaration styleDeclaration = entry.getValue(); if (styleDeclaration != null) { int length = styleDeclaration.getLength(); // Start selector startSelector(writer, selectorName, firstSelector); firstSelector = false; for (int i = 0; i < length; i++) { String propertyName = styleDeclaration.item(i); String propertyValue = styleDeclaration.getPropertyValue(propertyName); property(writer, propertyName, propertyValue); } // End selector endSelector(writer, selectorName); } } } /** * Build CSS Style Sheet content of the <code>element</code> Object by * using {@link CSSEngine} engine configuration. The serialization result is * stored into the <code>writer</code>. If * <code>serializeChildNodes</code> is true, the method will serialize too * the child nodes of the <code>element</code>. The * {@link CSSSerializerConfiguration} <code>configuration</code> is used * to generate selector with condition like Text[style='SWT.MULTI']. * * Map of <code>selectors</code> contains the selector already built. * * @param writer * @param engine * @param element * @param serializeChildNodes * @param selectors * @param configuration * @throws IOException */ protected void serialize(Writer writer, CSSEngine engine, Object element, boolean serializeChildNodes, Map<String, CSSStyleDeclaration> selectors, CSSSerializerConfiguration configuration) throws IOException { Element elt = engine.getElement(element); if (elt != null) { StringBuilder selectorName = new StringBuilder(elt.getLocalName()); CSSStyleDeclaration styleDeclaration = engine.getDefaultStyleDeclaration(element, null); if (configuration != null) { String[] attributesFilter = configuration.getAttributesFilter(); for (String attributeFilter : attributesFilter) { String value = elt.getAttribute(attributeFilter); if (value != null && value.length() > 0) { selectorName.append("["); selectorName.append(attributeFilter); selectorName.append("="); if (value.indexOf(".") != -1) { value = "'" + value + "'"; } selectorName.append(value); selectorName.append("]"); break; } } } selectors.put(selectorName.toString(), styleDeclaration); if (serializeChildNodes) { NodeList nodes = elt.getChildNodes(); if (nodes != null) { for (int k = 0; k < nodes.getLength(); k++) { serialize(writer, engine, nodes.item(k), serializeChildNodes, selectors, configuration); } } } } } /** * Generate start selector. * * @param writer * @param selectorName * @param firstSelector * @throws IOException */ protected void startSelector(Writer writer, String selectorName, boolean firstSelector) throws IOException { if (firstSelector == false) { writer.write("\n\n"); } writer.write(selectorName + " {"); } /** * Generate end selector. * * @param writer * @param selectorName * @throws IOException */ protected void endSelector(Writer writer, String selectorName) throws IOException { writer.write("\n}"); } /** * Generate CSS Property. * * @param writer * @param propertyName * @param propertyValue * @throws IOException */ private void property(Writer writer, String propertyName, String propertyValue) throws IOException { writer.write("\n\t" + propertyName + ":" + propertyValue + ";"); } }