001:/*
002: * Copyright (c) 2000, Jacob Smullyan.
003: *
004: * This is part of SkunkDAV, a WebDAV client. See http://skunkdav.sourceforge.net/
005: * for the latest version.
006: *
007: * SkunkDAV is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License as published
009: * by the Free Software Foundation; either version 2, or (at your option)
010: * any later version.
011: *
012: * SkunkDAV 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 GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with SkunkDAV; see the file COPYING. If not, write to the Free
019: * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
020: * 02111-1307, USA.
021:*/
022:
023:package org.skunk.dav.client.gui.editor;
024:
025:import java.util.ArrayList;
026:import java.util.Collections;
027:import java.util.Iterator;
028:import java.util.List;
029:import javax.swing.JComponent;
030:import javax.swing.SwingUtilities;
031:import org.skunk.assert.Assertion;
032:import org.skunk.dav.client.DAVConnection;
033:import org.skunk.dav.client.DAVConnectionPool;
034:import org.skunk.dav.client.DAVConstants;
035:import org.skunk.dav.client.DAVFile;
036:import org.skunk.dav.client.gui.DAVTreeModel;
037:import org.skunk.dav.client.gui.DAVTreeNode;
038:import org.skunk.dav.client.gui.Explorer;
039:import org.skunk.dav.client.gui.ExplorerApp;
040:import org.skunk.dav.client.gui.ExplorerView;
041:import org.skunk.dav.client.gui.StateMonitor;
042:import org.skunk.dav.client.gui.StateProperties;
043:import org.skunk.dav.client.gui.View;
044:import org.skunk.trace.Debug;
045:
046:public abstract class AbstractDAVEditor implements DAVEditor
047:{
048: private String name;
049: private byte[] resourceBody;
050: private boolean dirty;
051: private JComponent editingComponent;
052: private String resourceName;
053: private boolean writeable;
054: private List editListeners=Collections.synchronizedList(new ArrayList());
055: private DAVFile file;
056:
057: public AbstractDAVEditor(DAVFile file)
058: {
059: this .file=file;
060: if (file!=null)
061: {
062: setName(file.getFileName());
063: setResourceName(file.getFullName());
064: }
065: setDirty(false);
066: //this synchronizes the editor's DAVFile reference to the file in the explorer's TreeModel (our VFS)
067: StateMonitor.registerProperty(this ,
068: "DAVFile",
069: StateProperties.RELOAD,
070: getMapper(),
071: getDomainMatcher());
072: }
073:
074: private StateMonitor.Mapper getMapper()
075: {
076: return new StateMonitor.Mapper()
077: {
078: public Object getTargetValue(Object applicationValue)
079: {
080: Debug.trace(this , Debug.DP3, "in getTargetValue() with applicationValue of "+applicationValue);
081: Assertion.assert((applicationValue instanceof DAVTreeModel),
082: "we have a DAVTreeModel");
083: DAVTreeModel model=(DAVTreeModel) applicationValue;
084: //obtain appropriate DAVFile from treeModel
085: String fullPath=AbstractDAVEditor.this .getResourceName();
086: int lastSlash=fullPath.lastIndexOf("/");
087: String parentPath=fullPath.substring(0, lastSlash);
088: String filename=fullPath.substring(lastSlash+1);
089: DAVTreeNode node=model.getNodeMatchingPath(parentPath);
090: Debug.trace(this , Debug.DP3, "parentPath: {0}; filename: {1}; node: {2}",
091: new Object[] {parentPath, filename, node});
092: if (node!=null)
093: {
094: DAVFile parentFile=node.getDAVFile();
095: return parentFile.getChildNamed(AbstractDAVEditor.this .getDAVFile().getName());
096: }
097: return null;
098: }
099:
100: public boolean canMapValue(Object applicationValue)
101: {
102: return (applicationValue instanceof DAVTreeModel);
103: }
104: };
105: }
106:
107: private StateMonitor.DomainMatcher getDomainMatcher()
108: {
109: return new StateMonitor.DomainMatcher()
110: {
111: public boolean domainMatches(Object domainKey)
112: {
113: Debug.trace(this , Debug.DP3, "testing domainKey "+domainKey);
114: if (domainKey==null) return false;
115: String pathString=domainKey.toString();
116: String resourceString=AbstractDAVEditor.this .resourceName;
117: Debug.trace(this , Debug.DP3, "resourceString is "+resourceString);
118: if (resourceString.equals(pathString))
119: {
120: Debug.trace(this , Debug.DP3, "exact match");
121: return true;
122: }
123: else if (resourceString.startsWith(pathString))
124: {
125: Debug.trace(this , Debug.DP3, "resourceString {0} may match {1}",
126: new Object[] {resourceString, pathString});
127: //compare the last path element in the key with the corresponding
128: //element in the resource name
129: int pathLength=pathString.length();
130: pathLength=(pathString.endsWith("/"))
131: ? pathLength-1
132: : pathLength;
133: //this prevents pathString /foo/bar/ from matching with resourceString /foo/bar2/giblet
134: boolean result= (resourceString.charAt(pathLength)=='/');
135: Debug.trace(this , Debug.DP3, "did the domainKey match? "+result);
136: return result;
137: }
138: else return false;
139: }
140: };
141: }
142:
143: public void docking()
144: {
145: }
146:
147: public void undocking()
148: {
149: StateMonitor.unregisterProperty(this ,
150: "DAVFile",
151: StateProperties.RELOAD);
152: }
153:
154: public void setDAVFile(DAVFile file)
155: {
156: if (file==null)
157: {
158: handleNulledFile();
159: return;
160: }
161: Debug.trace(this , Debug.DP3, "DAVFile property now being set to "+file);
162: this .file=file;
163: }
164:
165: protected void handleNulledFile()
166: {
167: Debug.trace(this , Debug.DP3, "in handleNulledFile()");
168: //should do something here, put up a dialog, perhaps -- TO BE DONE
169: }
170:
171: public DAVFile getDAVFile()
172: {
173: return this .file;
174: }
175:
176: public void setName(String name)
177: {
178: this .name=name;
179: }
180:
181: public String getName()
182: {
183: return name;
184: }
185:
186: public byte[] getResourceBody()
187: {
188: return this .resourceBody;
189: }
190:
191: public void setResourceBody(byte[] resourceBody)
192: {
193: this .resourceBody=resourceBody;
194: }
195:
196: public String getResourceName()
197: {
198: return this .resourceName;
199: }
200:
201: public void setResourceName(String resourceName)
202: {
203: this .resourceName=resourceName;
204: }
205:
206: public boolean isDirty()
207: {
208: return this .dirty;
209: }
210:
211: public void setDirty(boolean dirty)
212: {
213: this .dirty=dirty;
214: View v=ExplorerApp.getViewForBuffer(this );
215: if (v instanceof ExplorerView)
216: {
217: ((ExplorerView) v).bufferDirtinessChanged(this );
218: }
219: }
220:
221: public boolean isWriteable()
222: {
223: return this .writeable;
224: }
225:
226: public void setWriteable(boolean writeable)
227: {
228: this .writeable=writeable;
229: }
230:
231: public abstract JComponent getComponent();
232:
233: public void save()
234: {
235: Debug.trace(this , Debug.DP3, "in save()");
236: EditEvent event=new EditEvent(this , EditEvent.SAVE);
237: fireEditEvent(event);
238: }
239:
240: public final void saveAs()
241: {
242: Debug.trace(this , Debug.DP3, "in saveAs()");
243: EditEvent event=new EditEvent(this , EditEvent.SAVE_AS);
244: fireEditEvent(event);
245: }
246:
247: public final void saveAs(String filename)
248: {
249: setResourceName(filename);
250: setName(filename);
251: save();
252: }
253:
254: public abstract void load() throws CannotLoadException;
255:
256:
257: public void addEditListener(EditListener ed)
258: {
259: editListeners.add(ed);
260: }
261:
262: public void removeEditListener(EditListener ed)
263: {
264: editListeners.remove(ed);
265: }
266:
267: private void fireEditEvent(EditEvent event)
268: {
269: for (Iterator it=editListeners.iterator();it.hasNext();)
270: {
271: ((EditListener)it.next()).editPerformed(event);
272: }
273: }
274:
275:
276:}
277:
278:/* $Log: AbstractDAVEditor.java,v $
279:/* Revision 1.16 2001/02/16 18:15:10 smulloni
280:/* many fixes to TextEditorCustomizer. FileMode and SyntaxStyle now have a
281:/* configData property (they will probably be made into sibling classes).
282:/*
283:/* Revision 1.15 2000/12/19 22:36:05 smulloni
284:/* adjustments to preamble.
285:/*
286:/* Revision 1.14 2000/12/08 05:50:30 smulloni
287:/* fixed MessageCatalogEditor. The spi features are now a special build option,
288:/* and editors are loaded through reflection.
289:/*
290:/* Revision 1.13 2000/12/07 00:01:34 smulloni
291:/* adding an additional editor, still hard-coded into the DAVEditorFactory.
292:/*
293:/* Revision 1.12 2000/12/03 23:53:26 smulloni
294:/* added license and copyright preamble to java files.
295:/*
296:/* Revision 1.11 2000/12/01 16:25:54 smullyan
297:/* improvements to look and feel; fixed NPE in DAVFile; new actions for text
298:/* editor
299:/*
300:/* Revision 1.10 2000/11/28 19:36:19 smullyan
301:/* some bug fixes; notes.
302:/*
303:/* Revision 1.9 2000/11/28 00:01:40 smullyan
304:/* added a status bar/minibuffer, with a location field showing the current line and
305:/* column number (for the SimpleTextEditor and kin only).
306:/*
307:/* Revision 1.8 2000/11/23 04:37:35 smullyan
308:/* editor and explorer now synch their files using the StateMonitor, which has
309:/* been improved significantly
310:/*
311:/* Revision 1.7 2000/11/20 23:30:23 smullyan
312:/* more editor integration work.
313:/*
314:/* Revision 1.6 2000/11/18 04:36:07 smullyan
315:/* work on StateMonitor and related functionality.
316:/*
317:/* Revision 1.5 2000/11/17 20:25:07 smullyan
318:/* new SaveAction; a StateMonitor being added to handle application state.
319:/*
320:/* Revision 1.4 2000/11/16 23:16:48 smullyan
321:/* more preliminary work on editor integration
322:/*
323:/* Revision 1.3 2000/11/15 20:17:05 smullyan
324:/* added a Buffer interface, which is a wrapper around a displayable component.
325:/*
326:/* Revision 1.2 2000/11/15 19:45:37 smullyan
327:/* beginning of revamp of application to include multiple buffers.
328:/*
329:/* Revision 1.1 2000/11/14 23:14:39 smullyan
330:/* first cut at editing framework
331:/* */
|