--- /dev/null
+/*
+ * Copyright (c) 2003-2004 Christopher Lenz and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Christopher Lenz - initial API and implementation
+ *
+ * $Id: CssStructureCreator.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
+ */
+
+package net.sourceforge.phpeclipse.css.ui.internal.compare;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.sourceforge.phpeclipse.core.model.ISourceReference;
+import net.sourceforge.phpeclipse.css.core.internal.parser.DefaultCssParser;
+import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
+import net.sourceforge.phpeclipse.css.core.model.IAtRule;
+import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
+import net.sourceforge.phpeclipse.css.core.model.IRule;
+import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
+import net.sourceforge.phpeclipse.css.core.parser.ICssParser;
+import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
+import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
+import net.sourceforge.phpeclipse.css.ui.CssUI;
+import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
+import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
+
+import org.eclipse.compare.IStreamContentAccessor;
+import org.eclipse.compare.internal.DocumentManager;
+import org.eclipse.compare.structuremergeviewer.IStructureComparator;
+import org.eclipse.compare.structuremergeviewer.IStructureCreator;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+
+/**
+ * TODO Check why the root node is not being displayed
+ */
+public class CssStructureCreator implements IStructureCreator {
+
+ // IStructureCreator Implementation ----------------------------------------
+
+ /*
+ * @see IStructureCreator#getName()
+ */
+ public String getName() {
+ return CssUIMessages.getString(
+ "CssStructureViewer.title"); //$NON-NLS-1$
+ }
+
+ /*
+ * @see IStructureCreator#getStructure(Object)
+ */
+ public IStructureComparator getStructure(final Object input) {
+ IDocument doc = DocumentManager.get(input);
+ if (doc == null) {
+ if (input instanceof IStreamContentAccessor) {
+ doc = createDocument((IStreamContentAccessor) input);
+ }
+ }
+ if (doc != null) {
+ CssNode node = new CssNode(doc);
+ ICssParser parser = new DefaultCssParser();
+ parser.setSource(doc);
+ try {
+ IRule[] rules = parser.parseRules(null);
+ for (int i = 0; i < rules.length; i++) {
+ node.addChild(createNode(node, rules[i], new HashMap()));
+ }
+ } catch (LexicalErrorException e) {
+ // just return null
+ } catch (SyntaxErrorException e) {
+ // just return null
+ }
+ return node;
+ }
+ return null;
+ }
+
+ /*
+ * @see IStructureCreator#locate(Object, Object)
+ */
+ public IStructureComparator locate(Object path, Object input) {
+ // TODO Find out what locate() is about and implement the functionality
+ return null;
+ }
+
+ /*
+ * @see IStructureCreator#getContents(Object, boolean)
+ */
+ public String getContents(Object node, boolean ignoreWhitespace) {
+ if (node instanceof CssNode) {
+ CssNode cssNode = (CssNode) node;
+ int ch;
+ InputStream in = null;
+ try {
+ StringBuffer buf = new StringBuffer();
+ in = cssNode.getContents();
+ while ((ch = in.read()) != -1) {
+ if (!ignoreWhitespace
+ || !CssTextUtils.isCssWhitespace((char) ch)) {
+ buf.append((char) ch);
+ }
+ }
+ return buf.toString();
+ } catch (IOException e) {
+ // just return an empty string
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e1) {
+ // ignore
+ }
+ }
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+ /*
+ * @see IStructureCreator#save(IStructureComparator, Object)
+ */
+ public void save(IStructureComparator node, Object input) {
+ // TODO Find out what save() is about and implement the functionality
+ }
+
+ // Private Methods ---------------------------------------------------------
+
+ private IDocument createDocument(IStreamContentAccessor content) {
+ IDocument document = null;
+ InputStreamReader in = null;
+ try {
+ in = new InputStreamReader(content.getContents());
+ StringBuffer buf = new StringBuffer();
+ int ch;
+ while ((ch = in.read()) != -1) {
+ buf.append((char) ch);
+ }
+ document = new Document(buf.toString());
+ DocumentManager.put(content, document);
+ CssTextTools tools = CssUI.getDefault().getTextTools();
+ tools.setupDocument(document);
+ } catch (CoreException e) {
+ CssUI.log(e);
+ } catch (IOException e) {
+ CssUI.log(e);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+ return document;
+ }
+
+ private CssNode createNode(CssNode parent, IRule rule, Map names) {
+ int typeCode = -1;
+ String name = ""; //$NON-NLS-1$
+ if (rule instanceof IAtRule) {
+ IAtRule atRule = (IAtRule) rule;
+ typeCode = CssNode.AT_RULE;
+ ISourceReference atKeyword = atRule.getName();
+ if (atKeyword != null) {
+ name = atKeyword.getSource();
+ }
+ } else if (rule instanceof IStyleRule) {
+ IStyleRule styleRule = (IStyleRule) rule;
+ typeCode = CssNode.STYLE_RULE;
+ ISourceReference selector = styleRule.getSelector();
+ if (selector != null) {
+ name = selector.getSource();
+ }
+ }
+ String id = name;
+ if (names.containsKey(name)) {
+ Integer count = (Integer) names.get(name);
+ id += count.toString();
+ names.put(name, new Integer(count.intValue() + 1));
+ } else {
+ names.put(name, new Integer(0));
+ }
+ IRegion region = rule.getSourceRegion();
+ CssNode node = new CssNode(parent, typeCode, id, name,
+ region.getOffset(), region.getLength());
+ IRule[] children = rule.getChildren();
+ if (children.length > 0) {
+ Map ruleNames = new HashMap();
+ for (int i = 0; i < children.length; i++) {
+ node.addChild(createNode(node, children[i], ruleNames));
+ }
+ }
+ IDeclaration[] properties = rule.getDeclarations();
+ if (properties.length > 0) {
+ Map propertyNames = new HashMap();
+ for (int i = 0; i < properties.length; i++) {
+ node.addChild(createNode(node, properties[i], propertyNames));
+ }
+ }
+ return node;
+ }
+
+ private CssNode createNode(CssNode parent, IDeclaration declaration,
+ Map names) {
+ String name = ""; //$NON-NLS-1$
+ ISourceReference property = declaration.getProperty();
+ if (property != null) {
+ name = property.getSource();
+ }
+ String id = name;
+ if (names.containsKey(name)) {
+ Integer count = (Integer) names.get(name);
+ id += count.toString();
+ names.put(name, new Integer(count.intValue() + 1));
+ } else {
+ names.put(name, new Integer(0));
+ }
+ IRegion region = declaration.getSourceRegion();
+ return new CssNode(parent, CssNode.DECLARATION, id, name,
+ region.getOffset(), region.getLength());
+ }
+
+}