intial source from ttp://www.sf.net/projects/wdte
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.css.ui / src / net / sourceforge / phpeclipse / css / ui / internal / compare / CssStructureCreator.java
1 /*
2  * Copyright (c) 2003-2004 Christopher Lenz and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     Christopher Lenz - initial API and implementation
10  * 
11  * $Id: CssStructureCreator.java,v 1.1 2004-09-02 18:11:49 jsurfer Exp $
12  */
13
14 package net.sourceforge.phpeclipse.css.ui.internal.compare;
15
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.InputStreamReader;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import net.sourceforge.phpeclipse.core.model.ISourceReference;
23 import net.sourceforge.phpeclipse.css.core.internal.parser.DefaultCssParser;
24 import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
25 import net.sourceforge.phpeclipse.css.core.model.IAtRule;
26 import net.sourceforge.phpeclipse.css.core.model.IDeclaration;
27 import net.sourceforge.phpeclipse.css.core.model.IRule;
28 import net.sourceforge.phpeclipse.css.core.model.IStyleRule;
29 import net.sourceforge.phpeclipse.css.core.parser.ICssParser;
30 import net.sourceforge.phpeclipse.css.core.parser.LexicalErrorException;
31 import net.sourceforge.phpeclipse.css.core.parser.SyntaxErrorException;
32 import net.sourceforge.phpeclipse.css.ui.CssUI;
33 import net.sourceforge.phpeclipse.css.ui.internal.CssUIMessages;
34 import net.sourceforge.phpeclipse.css.ui.text.CssTextTools;
35
36 import org.eclipse.compare.IStreamContentAccessor;
37 import org.eclipse.compare.internal.DocumentManager;
38 import org.eclipse.compare.structuremergeviewer.IStructureComparator;
39 import org.eclipse.compare.structuremergeviewer.IStructureCreator;
40 import org.eclipse.core.runtime.CoreException;
41 import org.eclipse.jface.text.Document;
42 import org.eclipse.jface.text.IDocument;
43 import org.eclipse.jface.text.IRegion;
44
45 /**
46  * TODO Check why the root node is not being displayed
47  */
48 public class CssStructureCreator implements IStructureCreator {
49
50         // IStructureCreator Implementation ----------------------------------------
51
52         /*
53          * @see IStructureCreator#getName()
54          */
55         public String getName() {
56                 return CssUIMessages.getString(
57                         "CssStructureViewer.title"); //$NON-NLS-1$
58         }
59
60         /*
61          * @see IStructureCreator#getStructure(Object)
62          */
63         public IStructureComparator getStructure(final Object input) {
64                 IDocument doc = DocumentManager.get(input);
65                 if (doc == null) {
66                         if (input instanceof IStreamContentAccessor) {
67                                 doc = createDocument((IStreamContentAccessor) input);
68                         }
69                 }
70                 if (doc != null) {
71                         CssNode node = new CssNode(doc);
72                         ICssParser parser = new DefaultCssParser();
73                         parser.setSource(doc);
74                         try {
75                                 IRule[] rules = parser.parseRules(null);
76                                 for (int i = 0; i < rules.length; i++) {
77                                         node.addChild(createNode(node, rules[i], new HashMap()));
78                                 }
79                         } catch (LexicalErrorException e) {
80                                 // just return null
81                         } catch (SyntaxErrorException e) {
82                                 // just return null
83                         }
84                         return node;
85                 }
86                 return null;
87         }
88
89         /*
90          * @see IStructureCreator#locate(Object, Object)
91          */
92         public IStructureComparator locate(Object path, Object input) {
93                 // TODO Find out what locate() is about and implement the functionality
94                 return null;
95         }
96
97         /*
98          * @see IStructureCreator#getContents(Object, boolean)
99          */
100         public String getContents(Object node, boolean ignoreWhitespace) {
101                 if (node instanceof CssNode) {
102                         CssNode cssNode = (CssNode) node;
103                         int ch;
104                         InputStream in = null;
105                         try {
106                                 StringBuffer buf = new StringBuffer();
107                                 in = cssNode.getContents();
108                                 while ((ch = in.read()) != -1) {
109                                         if (!ignoreWhitespace
110                                          || !CssTextUtils.isCssWhitespace((char) ch)) {
111                                                 buf.append((char) ch);
112                                         }
113                                 }
114                                 return buf.toString();
115                         } catch (IOException e) {
116                                 // just return an empty string
117                         } finally {
118                                 if (in != null) {
119                                         try {
120                                                 in.close();
121                                         } catch (IOException e1) {
122                                                 // ignore
123                                         }
124                                 }
125                         }
126                 }
127                 return ""; //$NON-NLS-1$
128         }
129
130         /*
131          * @see IStructureCreator#save(IStructureComparator, Object)
132          */
133         public void save(IStructureComparator node, Object input) {
134                 // TODO Find out what save() is about and implement the functionality
135         }
136
137         // Private Methods ---------------------------------------------------------
138
139         private IDocument createDocument(IStreamContentAccessor content) {
140                 IDocument document = null;
141                 InputStreamReader in = null;
142                 try {
143                         in = new InputStreamReader(content.getContents());
144                         StringBuffer buf = new StringBuffer();
145                         int ch;
146                         while ((ch = in.read()) != -1) {
147                                 buf.append((char) ch);
148                         }
149                         document = new Document(buf.toString());
150                         DocumentManager.put(content, document);
151                         CssTextTools tools = CssUI.getDefault().getTextTools();
152                         tools.setupDocument(document);
153                 } catch (CoreException e) {
154                         CssUI.log(e);
155                 } catch (IOException e) {
156                         CssUI.log(e);
157                 } finally {
158                         if (in != null) {
159                                 try {
160                                         in.close();
161                                 } catch (IOException e) {
162                                         // ignore
163                                 }
164                         }
165                 }
166                 return document;
167         }
168
169         private CssNode createNode(CssNode parent, IRule rule, Map names) {
170                 int typeCode = -1;
171                 String name = ""; //$NON-NLS-1$
172                 if (rule instanceof IAtRule) {
173                         IAtRule atRule = (IAtRule) rule;
174                         typeCode = CssNode.AT_RULE;
175                         ISourceReference atKeyword = atRule.getName();
176                         if (atKeyword != null) {
177                                 name = atKeyword.getSource();
178                         }
179                 } else if (rule instanceof IStyleRule) {
180                         IStyleRule styleRule = (IStyleRule) rule;
181                         typeCode = CssNode.STYLE_RULE;
182                         ISourceReference selector = styleRule.getSelector();
183                         if (selector != null) {
184                                 name = selector.getSource();
185                         }
186                 }
187                 String id = name;
188                 if (names.containsKey(name)) {
189                         Integer count = (Integer) names.get(name);
190                         id += count.toString();
191                         names.put(name, new Integer(count.intValue() + 1));
192                 } else {
193                         names.put(name, new Integer(0));
194                 }
195                 IRegion region = rule.getSourceRegion();
196                 CssNode node = new CssNode(parent, typeCode, id, name,
197                         region.getOffset(), region.getLength());
198                 IRule[] children = rule.getChildren();
199                 if (children.length > 0) {
200                         Map ruleNames = new HashMap();
201                         for (int i = 0; i < children.length; i++) {
202                                 node.addChild(createNode(node, children[i], ruleNames));
203                         }
204                 }
205                 IDeclaration[] properties = rule.getDeclarations();
206                 if (properties.length > 0) {
207                         Map propertyNames = new HashMap();
208                         for (int i = 0; i < properties.length; i++) {
209                                 node.addChild(createNode(node, properties[i], propertyNames));
210                         }
211                 }
212                 return node;
213         }
214
215         private CssNode createNode(CssNode parent, IDeclaration declaration,
216                 Map names) {
217                 String name = ""; //$NON-NLS-1$
218                 ISourceReference property = declaration.getProperty();
219                 if (property != null) {
220                         name = property.getSource();
221                 }
222                 String id = name;
223                 if (names.containsKey(name)) {
224                         Integer count = (Integer) names.get(name);
225                         id += count.toString();
226                         names.put(name, new Integer(count.intValue() + 1));
227                 } else {
228                         names.put(name, new Integer(0));
229                 }
230                 IRegion region = declaration.getSourceRegion();
231                 return new CssNode(parent, CssNode.DECLARATION, id, name,
232                         region.getOffset(), region.getLength());
233         }
234
235 }