001: /*
002: * Gruntspud
003: *
004: * Copyright (C) 2002 Brett Smith.
005: *
006: * Written by: Brett Smith <t_magicthize@users.sourceforge.net>
007: *
008: * This program is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Library General Public License
010: * as published by the Free Software Foundation; either version 2 of
011: * the License, or (at your option) any later version.
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Library General Public License for more details.
016: *
017: * You should have received a copy of the GNU Library General Public
018: * License along with this program; if not, write to the Free Software
019: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
020: */
021:
022: package gruntspud.project;
023:
024: import gruntspud.Constants;
025: import gruntspud.GruntspudContext;
026: import gruntspud.GruntspudUtil;
027:
028: import java.io.File;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.io.OutputStream;
032: import java.io.PrintWriter;
033: import java.util.Iterator;
034: import java.util.Stack;
035:
036: import javax.swing.AbstractListModel;
037: import javax.xml.parsers.ParserConfigurationException;
038: import javax.xml.parsers.SAXParser;
039: import javax.xml.parsers.SAXParserFactory;
040:
041: import org.xml.sax.Attributes;
042: import org.xml.sax.SAXException;
043: import org.xml.sax.helpers.DefaultHandler;
044:
045: public class ProjectListModel extends AbstractListModel {
046: private java.util.List projects = new java.util.ArrayList();
047: private File file;
048: private GruntspudContext context;
049:
050: public ProjectListModel(GruntspudContext context) {
051: this .context = context;
052: }
053:
054: public int indexOf(Project p) {
055: return projects.indexOf(p);
056: }
057:
058: public int indexOf(String name) {
059: for (int i = 0; i < projects.size(); i++) {
060: Project p = getProjectAt(i);
061: if (p.getName().equals(name))
062: return i;
063: }
064: return -1;
065: }
066:
067: public Project getProjectForFile(File f) {
068: try {
069: File fcanon = f.getCanonicalFile();
070: for (int i = 0; i < projects.size(); i++) {
071: Project p = getProjectAt(i);
072: if ((fcanon.getAbsolutePath() + File.separator)
073: .startsWith(p.getCanonicalHome()
074: .getAbsolutePath()
075: + File.separator))
076: return p;
077: }
078: } catch (IOException ioe) {
079: Constants.SYSTEM_LOG.error(
080: "Could not determine project for file "
081: + f.getAbsolutePath(), ioe);
082: }
083: return null;
084: }
085:
086: public int indexOf(File home) {
087: for (int i = 0; i < projects.size(); i++) {
088: Project p = getProjectAt(i);
089: try {
090: if (p.getHome().getCanonicalFile().equals(
091: home.getCanonicalFile())) {
092: return i;
093: }
094: } catch (IOException ioe) {
095: }
096:
097: }
098: return -1;
099: }
100:
101: public void add(Project project) {
102: int i = getSize();
103: projects.add(project);
104: fireIntervalAdded(this , i, i);
105: }
106:
107: public void removeProjectAt(int r) {
108: projects.remove(r);
109: fireIntervalRemoved(this , r, r);
110: }
111:
112: public void setProjectAt(int r, Project prj) {
113: projects.set(r, prj);
114: fireContentsChanged(this , r, r);
115: }
116:
117: public int getSize() {
118: return projects.size();
119: }
120:
121: public Object getElementAt(int index) {
122: return projects.get(index);
123: }
124:
125: public Project getProjectAt(int index) {
126: return (Project) getElementAt(index);
127: }
128:
129: public void save(OutputStream out) throws IOException {
130: PrintWriter writer = new PrintWriter(out);
131: writer.print("<?xml version=\"1.0\"?>\n");
132: writer.print("<Projects>\n");
133: for (Iterator i = projects.iterator(); i.hasNext();) {
134: Project p = (Project) i.next();
135: writer.print(" <Project name=\"");
136: writer.print(p.getName());
137: writer.print("\" home=\"");
138: writer.print(p.getHome() == null ? "" : p.getHome()
139: .getAbsolutePath());
140: writer.print("\" flatMode=\"");
141: writer.print(String.valueOf(p.isFlatMode()));
142: writer.print("\" defaultFilter=\"");
143: writer.print(p.getDefaultFilter() == null ? "" : p
144: .getDefaultFilter());
145: writer.print("\">\n <Description>");
146: writer.print(p.getDescription() == null ? ""
147: : GruntspudUtil.encodeXML(p.getDescription()));
148: writer.print("</Description>\n </Project>\n");
149: }
150: writer.print("</Projects>");
151: writer.flush();
152: }
153:
154: public void load(InputStream in) throws IOException, SAXException,
155: ParserConfigurationException {
156: SAXParserFactory saxFactory = SAXParserFactory.newInstance();
157: SAXParser saxParser = saxFactory.newSAXParser();
158: saxParser.parse(in, new ProjectsSAXHandler());
159: }
160:
161: private class ProjectsSAXHandler extends DefaultHandler {
162: private String PROJECTS_ELEMENT = "Projects";
163: private String PROJECT_ELEMENT = "Project";
164: private String NAME_ATTRIBUTE = "name";
165: private String DESCRIPTION_ELEMENT = "Description";
166: private String HOME_ATTRIBUTE = "home";
167: private String DEFAULT_FILTER_ATTRIBUTE = "defaultFilter";
168: private String FLAT_MODE = "flatMode";
169: private Project currentProject = null;
170: private Stack tags = new Stack();
171:
172: public void startElement(String uri, String localName,
173: String qname, Attributes attrs) throws SAXException {
174: ElementWrapper currentElement = tags.size() == 0 ? null
175: : (ElementWrapper) tags.peek();
176: if (currentElement == null) {
177: if (!qname.equals(PROJECTS_ELEMENT)) {
178: throw new SAXException("Unexpected root element <"
179: + qname + ">");
180: }
181: } else {
182: if (currentElement.element.equals(PROJECTS_ELEMENT)) {
183: if (qname.equals(PROJECT_ELEMENT)) {
184: String name = attrs.getValue(NAME_ATTRIBUTE);
185: if (name == null) {
186: throw new SAXException(NAME_ATTRIBUTE
187: + " attribute must be specified");
188: }
189: currentProject = new Project(name);
190: String home = attrs.getValue(HOME_ATTRIBUTE);
191: if (home == null) {
192: throw new SAXException(HOME_ATTRIBUTE
193: + " attribute must be specified");
194: }
195: currentProject.setHome(new File(home));
196: String defaultFilter = attrs
197: .getValue(DEFAULT_FILTER_ATTRIBUTE);
198: currentProject.setDefaultFilter(defaultFilter);
199: currentProject.setFlatMode(Boolean.TRUE
200: .toString().equals(
201: attrs.getValue(FLAT_MODE)));
202: projects.add(currentProject);
203: } else {
204: throw new SAXException("Unexpected element <"
205: + qname + ">");
206: }
207: } else if (currentElement.element
208: .equals(PROJECT_ELEMENT)) {
209: if (qname.equals(DESCRIPTION_ELEMENT)) {
210: //
211: } else {
212: throw new SAXException("Unexpected element <"
213: + qname + ">");
214: }
215: } else {
216: throw new SAXException("Unexpected element <"
217: + qname + ">");
218: }
219: }
220: ElementWrapper w = new ElementWrapper(qname);
221: tags.push(w);
222:
223: }
224:
225: public void characters(char[] ch, int start, int len)
226: throws SAXException {
227: ElementWrapper currentElement = tags.size() == 0 ? null
228: : (ElementWrapper) tags.peek();
229: if (currentElement != null)
230: currentElement.text.append(new String(ch, start, len));
231: else
232: throw new SAXException("Unexpected text at " + start
233: + " for " + len);
234: }
235:
236: public void endElement(String uri, String localName,
237: String qname) throws SAXException {
238: ElementWrapper currentElement = tags.size() == 0 ? null
239: : (ElementWrapper) tags.peek();
240: if (currentElement != null) {
241: if (!currentElement.element.equals(qname)) {
242: throw new SAXException(
243: "Unexpected end element found <" + qname
244: + ">");
245: }
246: if (currentElement.element.equals(DESCRIPTION_ELEMENT))
247: currentProject.setDescription(currentElement.text
248: .toString());
249: tags.pop();
250: }
251: }
252: }
253:
254: public class ElementWrapper {
255: String element;
256: StringBuffer text;
257:
258: ElementWrapper(String element) {
259: this .element = element;
260: text = new StringBuffer();
261: }
262: }
263: }
|