001: /*
002: * Copyright (C) 2001, 2002 Robert MacGrogan
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2.1 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: *
019: * $Archive: SourceJammer$
020: * $FileName: GuiConf.java$
021: * $FileID: 4116$
022: *
023: * Last change:
024: * $AuthorName: Rob MacGrogan$
025: * $Date: 7/31/03 12:48 PM$
026: * $VerID: 9232$
027: * $Comment: Fix "read-only bug". Test to make sure directory is
028: * really read only before throwing exception.$
029: *
030: * $KeyWordsOff: $
031: */
032:
033: package org.sourcejammer.client.gui.conf;
034:
035: import org.sourcejammer.util.AppConfig;
036: import java.io.*;
037: import org.w3c.dom.*;
038: import org.sourcejammer.xml.*;
039: import org.sourcejammer.project.view.Project;
040: import org.sourcejammer.project.view.NodeName;
041: import java.util.Stack;
042:
043: import javax.xml.parsers.DocumentBuilderFactory;
044: import javax.xml.parsers.ParserConfigurationException;
045: import javax.xml.transform.TransformerException;
046:
047: import org.xml.sax.SAXException;
048: import org.sourcejammer.util.ConfigurationException;
049: import org.sourcejammer.util.StringUtil;
050:
051: /**
052: * Title: SourceJammer v 0.1.0
053: * Description:
054: * Copyright: Copyright (c) 2001
055: * Company:
056: * @author Robert MacGrogan
057: * @version $Revision: 1.3 $
058: */
059:
060: public class GuiConf {
061:
062: public static final String GUI_CONF_ROOT_NODE = "UserArchiveConfig";
063: public static final String DEFAULT_DIRECTORIES_NODE = "DefaultDirectories";
064:
065: public static final String SPACE_REPLACER = "_xxxSJSPACExxx_";
066: public static final String QUOTE_REPLACER = "_xxxSJSGQUOTxxx_";
067: public static final String NUM_BEGINNER = "_xxxSJNUMBEGINNERxxx_";
068:
069: File mflGuiConf = null;
070: Document mdocGuiConfXML = null;
071: Element melmDefaultDirectories = null;
072:
073: public GuiConf(String archiveName, String userName)
074: throws IOException {
075: AppConfig oConf = AppConfig.getInstance();
076:
077: String sConfFileName = archiveName + "." + userName;
078: mflGuiConf = new File(oConf.getConfigFilePath(), sConfFileName);
079: if (mflGuiConf.exists()) {
080: try {
081: mdocGuiConfXML = XMLUtil.getXMLDoc(mflGuiConf);
082: Element elmRoot = mdocGuiConfXML.getDocumentElement();
083: try {
084: melmDefaultDirectories = XMLUtil.getChildElement(
085: DEFAULT_DIRECTORIES_NODE, elmRoot);
086: } catch (XMLNodeDoesNotExistException ex) {
087: melmDefaultDirectories = XMLUtil
088: .addNewChildElement(
089: DEFAULT_DIRECTORIES_NODE, elmRoot);
090: saveConfFile();
091: }
092: } catch (SAXException ex) {
093: throw new ConfigurationException(
094: "Local configuration file for this archive and user is corrupted.");
095: } catch (ParserConfigurationException ex) {
096: throw new ConfigurationException(
097: "Local configuration file for this archive and user is corrupted.");
098: }
099: } else {
100: try {
101: mdocGuiConfXML = DocumentBuilderFactory.newInstance()
102: .newDocumentBuilder().newDocument();
103: } catch (ParserConfigurationException ex) {
104: throw new IOException(
105: "Exception in creating default directory conf doc.");
106: }
107: Element elmRoot = XMLUtil.addRootElement(
108: GUI_CONF_ROOT_NODE, mdocGuiConfXML);
109: melmDefaultDirectories = XMLUtil.addNewChildElement(
110: DEFAULT_DIRECTORIES_NODE, elmRoot);
111: saveConfFile();
112: }
113: }
114:
115: private synchronized void saveConfFile() throws IOException {
116: try {
117: XMLUtil.writeXMLDocToFileSys(mdocGuiConfXML, mflGuiConf);
118: } catch (TransformerException ex) {
119: throw new IOException(
120: "Transformer exception in saving default directory file.");
121: }
122: }
123:
124: public void setDefaultWorkingDirectory(NodeName nodeName,
125: File directory) throws IOException,
126: XMLNodeDoesNotExistException {
127:
128: if (directory == null) {
129: throw new IOException("The directory File is null.");
130: }
131:
132: if (!directory.isDirectory()) {
133: throw new IOException(directory.getAbsolutePath()
134: + " is not a directory.");
135: }
136: if (!directory.canWrite()) {
137: //Let's try to create a test file first to see if we really can't write.
138: File test = new File(directory, "_testfile.sj");
139: boolean fileCreated = false;
140: try {
141: fileCreated = test.createNewFile();
142: } catch (IOException ex) {
143: fileCreated = false;
144: }
145:
146: if (!fileCreated) {
147: throw new IOException(
148: "SourceJammer Cannot write to "
149: + directory.getAbsolutePath()
150: + ". The directory is read-only.\r\nA directory must be writable to be a default directory for SourceJammer.");
151: } else {
152: test.delete();
153: }
154: }
155:
156: if (!directory.exists()) {
157: directory.mkdir();
158: }
159:
160: Stack oNameStack = getInvertedNodeNameStack(nodeName);
161:
162: Element elmProjectElement = melmDefaultDirectories;
163: //Feature Request Number 472853
164: // oNameStack.pop();
165: while (!oNameStack.isEmpty()) {
166: String sProj = (String) oNameStack.pop();
167: elmProjectElement = getConfElement(elmProjectElement, sProj);
168: }
169:
170: String sDirPath = directory.getAbsolutePath();
171: //sDirPath = StringUtil.replaceSubstring(sDirPath, " ", SPACE_REPLACER);
172: //sDirPath = StringUtil.replaceSubstring(sDirPath, "'", QUOTE_REPLACER);
173: //sDirPath = fixBeginningNumber(sDirPath);
174: XMLUtil.addOrReplaceElementText(elmProjectElement, directory
175: .getAbsolutePath());
176: saveConfFile();
177: }
178:
179: private String projectNameToLegalDOM(String name) {
180: String newName = StringUtil.replaceSubstring(name, " ",
181: SPACE_REPLACER);
182: newName = StringUtil.replaceSubstring(newName, "'",
183: QUOTE_REPLACER);
184: newName = fixBeginningNumber(newName);
185: return newName;
186: }
187:
188: public File getDefaultWorkingDirectory(NodeName oNodeName)
189: throws IOException {
190: File flDefaultDirectory = null;
191: Stack oNameStack = getInvertedNodeNameStack(oNodeName);
192: String sDirectory = null;
193: Element elmProject = melmDefaultDirectories;
194: //Pop stack once to skip over archive name.
195: //Feature Request Number 472853
196: // oNameStack.pop();
197: while (!oNameStack.isEmpty()) {
198: String sProj = (String) oNameStack.pop();
199: elmProject = getConfElement(elmProject, sProj);
200: String sTemp = XMLUtil.getStringFromNode(elmProject, "");
201: if (sTemp != null && !sTemp.equals("")) {
202: sDirectory = sTemp;
203: } else if (sDirectory != null && !sDirectory.equals("")) {
204: sDirectory = sDirectory + File.separator + sProj;
205: }
206: }
207: if (sDirectory != null && !sDirectory.equals("")) {
208: flDefaultDirectory = new File(sDirectory.trim());
209: }
210: return flDefaultDirectory;
211: }
212:
213: private String fixBeginningNumber(String s) {
214: String sReturn = null;
215: if (Character.isDigit(s.charAt(0))) {
216: //Begins with digit, so append string.
217: sReturn = NUM_BEGINNER + s;
218: } else {
219: sReturn = s;
220: }
221: return sReturn;
222: }
223:
224: private Element getConfElement(Element parent, String name)
225: throws IOException {
226: Element elmReturn = null;
227: try {
228: name = projectNameToLegalDOM(name);
229: elmReturn = XMLUtil.getChildElement(name, parent);
230: } catch (XMLNodeDoesNotExistException ex) {
231: //then create it.
232: elmReturn = XMLUtil.addNewChildElement(name, parent);
233: saveConfFile();
234: }
235: return elmReturn;
236: }
237:
238: private Stack getInvertedNodeNameStack(NodeName nodeName) {
239: //First we need to invert project name, so it goes from root to project, instead
240: //of vice versa
241: Stack oNameStack = new Stack();
242: NodeName oParentName = nodeName;
243: while (oParentName != null) {
244: oNameStack.push(oParentName.getName());
245: oParentName = oParentName.getParent();
246: }
247: return oNameStack;
248: }
249:
250: /*
251: public static void main(String[] args){
252: try {
253: Document doc = new DocumentImpl();
254: Element elmRoot = XMLUtil.addRootElement(GUI_CONF_ROOT_NODE, doc);
255: Element elmDir = XMLUtil.addNewChildElement(DEFAULT_DIRECTORIES_NODE, elmRoot);
256:
257: XMLUtil.addOrReplaceElementText(elmDir, "c:\\rob\\monkey\\pants");
258:
259: Element elm = XMLUtil.addNewChildElement("test", "Hello.", elmDir );
260:
261: System.out.println("\r\n\r\n");
262: System.out.println(XMLUtil.xmlDocToStringBuffer(doc, true).toString());
263: System.out.println("\r\n\r\n");
264:
265: XMLUtil.addOrReplaceElementText(elm, "Goodbye!");
266: XMLUtil.addOrReplaceElementText(elmDir, "c:\\rob\\envelope\\soda");
267: System.out.println(XMLUtil.xmlDocToStringBuffer(doc, true).toString());
268:
269: }
270: catch (Exception ex){
271: ex.printStackTrace();
272: }
273: }
274: */
275: }
|