Source Code Cross Referenced for DAVTreeModel.java in  » Net » SkunkDAV » org » skunk » dav » client » gui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » SkunkDAV » org.skunk.dav.client.gui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:/*
0002: *  Copyright (c) 2000, Jacob Smullyan.
0003: *
0004: *  This is part of SkunkDAV, a WebDAV client.  See http://skunkdav.sourceforge.net/ 
0005: *  for the latest version.
0006: * 
0007: *  SkunkDAV is free software; you can redistribute it and/or
0008: *  modify it under the terms of the GNU General Public License as published
0009: *  by the Free Software Foundation; either version 2, or (at your option)
0010: *  any later version.
0011: * 
0012: *  SkunkDAV  is distributed in the hope that it will be useful,
0013: *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0014: *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015: *  General Public License for more details.
0016: * 
0017: *  You should have received a copy of the GNU General Public License
0018: *  along with SkunkDAV; see the file COPYING.  If not, write to the Free
0019: *  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
0020: *  02111-1307, USA.
0021:*/
0022:
0023:package org.skunk.dav.client.gui;
0024:
0025:import java.io.IOException;
0026:import java.util.Iterator;
0027:import java.util.Map;
0028:import java.util.StringTokenizer;
0029:import javax.swing.JOptionPane;
0030:import javax.swing.SwingUtilities;
0031:import javax.swing.tree.DefaultMutableTreeNode;
0032:import javax.swing.tree.DefaultTreeModel;
0033:import javax.swing.tree.MutableTreeNode;
0034:import javax.swing.tree.TreeNode;
0035:import javax.swing.tree.TreePath;
0036:import org.skunk.assert.Assertion;
0037:import org.skunk.dav.client.DAVAuthenticator;
0038:import org.skunk.dav.client.DAVConnection;
0039:import org.skunk.dav.client.DAVConnectionPool;
0040:import org.skunk.dav.client.DAVConstants;
0041:import org.skunk.dav.client.DAVException;
0042:import org.skunk.dav.client.DAVFile;
0043:import org.skunk.dav.client.DAVProperty;
0044:import org.skunk.dav.client.Depth;
0045:import org.skunk.dav.client.method.CopyMethod;
0046:import org.skunk.dav.client.method.DeleteMethod;
0047:import org.skunk.dav.client.method.GetMethod;
0048:import org.skunk.dav.client.method.LockMethod;
0049:import org.skunk.dav.client.method.MkcolMethod;
0050:import org.skunk.dav.client.method.MoveMethod;
0051:import org.skunk.dav.client.method.PropFindMethod;
0052:import org.skunk.dav.client.method.PropFindQueryType;
0053:import org.skunk.dav.client.method.PropPatchMethod;
0054:import org.skunk.dav.client.method.PutMethod;
0055:import org.skunk.dav.client.method.UnlockMethod;
0056:import org.skunk.trace.Debug;
0057:
0058:public class DAVTreeModel extends DefaultTreeModel 
0059:{ 
0060:
0061:    private static boolean DO_ALLPROP;  
0062:    static 
0063:    {
0064:	/*
0065:	 * allProp is an experimental property, for testing.
0066:	 * setting it to false may cause tree model queries to be more efficient,
0067:	 * and enables the app to work with some recalcitrant dav server implementations
0068:	 * that don't like allprop.  However, at present it breaks some other features.
0069:	 */
0070:	String doAllprop=System.getProperty("doAllprop");
0071:	if (doAllprop!=null && doAllprop.equalsIgnoreCase("false"))
0072:	    DO_ALLPROP=false;
0073:	else DO_ALLPROP=true;
0074:    }
0075:
0076:    private boolean showNonCollections;
0077:
0078:    public static final boolean usesAllprop()
0079:    {
0080:	return DAVTreeModel.DO_ALLPROP;
0081:    }
0082:
0083:
0084:    public DAVTreeModel(DefaultMutableTreeNode rootNode)
0085:    {
0086:	this (rootNode, false);
0087:    }
0088:
0089:    public DAVTreeModel(DefaultMutableTreeNode rootNode, boolean showNonCollections)
0090:    {
0091:	super (rootNode);
0092:	this .showNonCollections=showNonCollections;
0093:
0094:	Debug.trace(this , Debug.DP3, "in constructor: rootNode {0}, show non-collections: {1}",
0095:		    new Object[] { rootNode, new Boolean(showNonCollections)});
0096:    }
0097:
0098:    public boolean getShowNonCollections()
0099:    {
0100:	return this .showNonCollections;
0101:    }
0102:
0103:    public boolean isLeaf(Object node)
0104:    {
0105:	if (node instanceof  DAVTreeNode)
0106:	{
0107:	    return ((DAVTreeNode)node).isLeaf();
0108:	}
0109:	else if (node.equals(getRoot()))
0110:	    return false;
0111:	else 
0112:	{
0113:	    return super .isLeaf(node);
0114:	}
0115:    }
0116:
0117:    public Object getChild(Object parent, int index)
0118:    {
0119:	testNode(parent);
0120:	return super .getChild(parent, index);
0121:    }
0122:
0123:    public int getChildCount(Object parent)
0124:    {
0125:	testNode(parent);
0126:	return super .getChildCount(parent);
0127:    }
0128:
0129:    public int getIndexOfChild(Object parent, Object child)
0130:    {
0131:	Debug.trace(this , Debug.DP6, 
0132:		    "getting index of child for parent {0} and child {1}",
0133:		    new Object[] {parent, child} );
0134:	testNode(parent);
0135:	return super .getIndexOfChild(parent, child);
0136:    }
0137:
0138:    /**
0139:     *  if the node has not been refreshed and is a collection, refresh it
0140:     */
0141:    public void testNode(Object node)
0142:    {
0143:	if (node instanceof  DAVTreeNode)
0144:	{
0145:	    DAVTreeNode davnode=(DAVTreeNode) node;
0146:	    if (!(davnode.isRefreshed() || davnode.isLeaf()))
0147:	    {
0148:		refreshNode(davnode);
0149:	    }
0150:	}
0151:    }
0152:
0153:    private void reloadNode(final DAVTreeNode node)
0154:    {
0155:	BusinessTracker.addBusy("reload");
0156:	Runnable r=new Runnable() {
0157:		public void run()
0158:		{
0159:		    Debug.trace(this , Debug.DP3, "refreshing {0}", 
0160:				new Object[] {node});
0161:		    refreshNode(node); //why am I doing this in the event dispatch thread?
0162:		    reload(node);
0163:		    BusinessTracker.removeBusy("reload");
0164:		}
0165:	    };
0166:	if (SwingUtilities.isEventDispatchThread())
0167:	    r.run();
0168:	else SwingUtilities.invokeLater(r);
0169:    }
0170:
0171:    public void refreshNode(DAVTreeNode node)
0172:    {
0173:	refreshNode(node, DO_ALLPROP);
0174:    }
0175:
0176:    public void refreshNode(DAVTreeNode node, boolean doAllprop)
0177:    {
0178:	BusinessTracker.addBusy("refresh");
0179:	synchronized (node)
0180:	{
0181:	    String resource=node.getDAVFile().getName();
0182:	    PropFindMethod method=(doAllprop) 
0183:		? new PropFindMethod(resource)
0184:		: new PropFindMethod(resource, Depth.ONE, DAVProperty.BASIC_PROPERTIES);
0185:
0186:	    DAVFile newFile=null;
0187:	    try
0188:	    {
0189:		DAVConnection conn=node.getDAVFile().getDAVConnection();
0190:		conn.execute(method);
0191:		newFile=method.getDAVFile();
0192:	    }			
0193:	    catch (DAVException davie)
0194:	    {
0195:		Debug.trace(this , Debug.DP2, davie);
0196:	    }
0197:	    catch (IOException oyVeh)
0198:	    {
0199:		Debug.trace(this , Debug.DP2, oyVeh);
0200:	    }
0201:	    if (newFile!=null) 
0202:	    {
0203:		Debug.trace(this , Debug.DP3, "refreshed file:\n"+newFile.toVerboseString());
0204:		node.setDAVFile(newFile);
0205:		node.setRefreshed(true);
0206:		StateMonitor.setProperty(StateProperties.RELOAD, 
0207:					 this ,                   //reference to DAVTreeModel is application value
0208:					 newFile.getFullName()); //full path of resource is domain key
0209:	    }
0210:	    else 
0211:	    {
0212:		Debug.trace(this , Debug.DP2, "refresh on {0} failed", new Object[] {node});
0213:	    }
0214:	    BusinessTracker.removeBusy("refresh");
0215:	}
0216:    }
0217:
0218:    private void addConnection(DAVTreeNode node)
0219:    {
0220:	BusinessTracker.addBusy("addConn");
0221:	Object root=getRoot();
0222:	if (root instanceof  DefaultMutableTreeNode)
0223:	{
0224:	    ((DefaultMutableTreeNode) root).add(node);
0225:	    reload();
0226:	}
0227:	else 
0228:	{
0229:	    Debug.trace(this , Debug.DP2, 
0230:			"Programming Error -- root node not a DefaultMutableTreeNode");
0231:	}
0232:	BusinessTracker.removeBusy("addConn");
0233:    }
0234:
0235:    public DAVTreeNode addConnectionNode(ServerData sd, boolean waitForIt, Runnable postRunner)
0236:    {
0237:	BusinessTracker.addBusy("addNode");
0238:	String host=sd.getHost();
0239:	int port=sd.getPort();
0240:	String initialPath=sd.getInitialPath();
0241:	Object nodeObj=getConnectionNode(host, port);	
0242:	if (nodeObj!=null && nodeObj instanceof  DAVTreeNode)
0243:	{	    
0244:	    DAVTreeNode possibleNode=(DAVTreeNode) nodeObj;
0245:	    String nodePath=possibleNode.getDAVFile().getName();
0246:	    Debug.trace(this , Debug.DP3, "possible node found, path is {0}",
0247:			new Object[] {nodePath});
0248:	    /*
0249:	      four possibilities for the new initial path: 
0250:	      1. the same initial path.  Do not connect.
0251:	      2. a subpath.  Do not connect.
0252:	      3. a superpath.  remove possibleNode and connect.
0253:	      4. a parallel path.  Connect, leave possibleNode alone.
0254:	    */
0255:	    if (initialPath.startsWith(nodePath)) //cases 1 and 2
0256:	    {
0257:		if (!initialPath.equals(nodePath))
0258:		{
0259:		    String fullPath=new StringBuffer(host)
0260:			.append(':')
0261:			.append(port)
0262:			.append(initialPath)
0263:			.toString();
0264:		    DAVTreeNode desiredNode=getNodeMatchingPath(fullPath);
0265:		    BusinessTracker.removeBusy("addNode");
0266:		    return desiredNode;
0267:		    
0268:		}
0269:		BusinessTracker.removeBusy("addNode");
0270:		return possibleNode;
0271:	    }
0272:	    if (nodePath.startsWith(initialPath)) //case 3
0273:	    {
0274:		removeNodeFromParent(possibleNode);	
0275:	    }	      
0276:	}	
0277:	DAVAuthenticator auth=new DAVAuthenticatorImpl(sd);
0278:	DAVTreeNode node=_addConnectionNode(sd.usesSSL(), 
0279:					    host, 
0280:					    port, 
0281:					    initialPath, 
0282:					    auth, 
0283:					    waitForIt,
0284:					    postRunner);
0285:	BusinessTracker.removeBusy("addNode");
0286:	return node;
0287:    }
0288:
0289:    public DAVTreeNode addConnectionNode(ServerData sd, Runnable postRunner)
0290:    {
0291:	return addConnectionNode(sd, false, postRunner);
0292:    }
0293:
0294:    private synchronized DAVTreeNode  _addConnectionNode(final boolean usingSSL,
0295:						 final String host, 
0296:						 final int port, 
0297:						 final String initialPath, 
0298:						 final DAVAuthenticator auth,
0299:						 final boolean waitForIt,
0300:						 final Runnable postRunner)
0301:    {
0302:	final DAVTreeNode retNode=null;
0303:	Thread t=new Thread() {
0304:		public void run() {
0305:		    DAVConnection dc=DAVConnectionPool.getDAVConnection(host, port, usingSSL);
0306:		    ExplorerApp.getAppContext().getConfigurator().configure(dc);
0307:		    Debug.trace(this , Debug.DP4, "configured new connection: its timeout is {0}",
0308:				new Integer(dc.getSocketTimeout()));
0309:		    dc.setAuthenticator(auth);
0310:		    PropFindMethod method;
0311:		    if (DO_ALLPROP) 
0312:			method=new PropFindMethod(initialPath);
0313:		    else
0314:			method=new PropFindMethod(initialPath, Depth.ONE, DAVProperty.BASIC_PROPERTIES);
0315:		    try
0316:		    {
0317:			dc.execute(method);
0318:			if (method.getStatus()>=400) 
0319:			    return;
0320:			DAVFile file=method.getDAVFile();
0321:			final DAVTreeNode newNode=new DAVTreeNode(file, getShowNonCollections());
0322:			newNode.setShowingHost(true); //display host, port and path
0323:			retNode=newNode;
0324:				    
0325:			Runnable runner=new Runnable() 
0326:			    {
0327:				public void run() 
0328:				{
0329:				    addConnection(newNode);
0330:				    if (postRunner!=null)
0331:					postRunner.run();
0332:				}
0333:			    };
0334:
0335:			if (!waitForIt)
0336:			{
0337:			    SwingUtilities.invokeLater(runner);
0338:			}
0339:			else 
0340:			{
0341:			    runner.run();
0342:			}
0343:		    }
0344:		    catch (Exception ugh)
0345:		    {
0346:			final Exception ugh2=ugh;
0347:			Debug.trace(this , Debug.DP2, ugh);
0348:			SwingUtilities.invokeLater(new Runnable() {
0349:				public void run() {
0350:				    String message=ResourceManager
0351:					.getMessage(ResourceManager.CONNECTION_ERROR_MESSAGE, 
0352:						    new Object[] { new StringBuffer(host)
0353:								   .append(':')
0354:								   .append(port)
0355:								   .toString(), 
0356:								   ugh2.getMessage() } );
0357:				    String title=ResourceManager
0358:					.getMessage(ResourceManager.ERROR_DIALOG_TITLE);
0359:				    JOptionPane.showMessageDialog(Explorer.guessActiveExplorer(),
0360:								  message, 
0361:								  title,
0362:								  JOptionPane.ERROR_MESSAGE);
0363:				}
0364:			    });
0365:		    }
0366:		}
0367:	    };
0368:	if (waitForIt)
0369:	    t.run();
0370:	else
0371:	    t.start();
0372:	return retNode;
0373:    }
0374:
0375:    public void removeConnectionNode(String host, int port, String initialPath)
0376:    {
0377:	Object child=getConnectionNode(host, port, initialPath);
0378:	if (child instanceof  MutableTreeNode)
0379:	    removeNodeFromParent((MutableTreeNode)child);
0380:	DAVConnectionPool.removeDAVConnection(host, port);
0381:    }
0382:
0383:    public void removeConnectionNode(ServerData sd)
0384:    {
0385:	Assertion.assert((sd!=null), "serverData is not null");
0386:	removeConnectionNode(sd.getHost(), sd.getPort(), sd.getInitialPath());
0387:    }
0388:
0389:    private Object getConnectionNode(String host, int port, String initialPath)
0390:    {
0391:	Object root=getRoot();
0392:	String connName=new StringBuffer(host)
0393:	    .append(':')
0394:	    .append(port)
0395:	    .append(initialPath)
0396:	    .toString();
0397:	for (int i=0;i<getChildCount(root);i++)
0398:	{
0399:	    Object child=getChild(root, i);
0400:	    if (child.toString().equals(connName))
0401:	    {
0402:		    return child;
0403:	    }
0404:	}
0405:	return null;
0406:    }
0407:
0408:    private Object getConnectionNode(String host, int port)
0409:    {
0410:	Object root=getRoot();
0411:	String connName=new StringBuffer(host)
0412:	    .append(':')
0413:	    .append(port)
0414:	    .append('/')
0415:	    .toString();
0416:	for (int i=0;i<getChildCount(root);i++)
0417:	{
0418:	    Object child=getChild(root, i);
0419:	    if (child.toString().startsWith(connName))
0420:	    {
0421:		    return child;
0422:	    }
0423:	}
0424:	return null;
0425:    }	
0426:
0427:    public byte[] get(DAVFile file)
0428:    {
0429:	BusinessTracker.addBusy(file);
0430:	DAVConnection dc=DAVConnectionPool.getDAVConnection(file.getHost(), file.getPort());
0431:	GetMethod method=new GetMethod(file.getName());
0432:	byte[] body=null;
0433:	try
0434:	{
0435:	    dc.execute(method);
0436:	    int status=method.getStatus();
0437:	    Debug.trace(this , Debug.DP3, "status of response: {0}", 
0438:			new Object[] {new Integer(status) });
0439:	    if (status>=400)
0440:	    {
0441:		handleStatusError(file.getName(), status, method.getResponseBody());
0442:	    }
0443:	    else body=method.getResponseBody();
0444:	}
0445:	catch (Exception davie)
0446:	{
0447:	    Debug.trace(this , Debug.DP2, davie);
0448:	    handleConnectionError(davie, file.getHost(), file.getPort());
0449:	}
0450:	BusinessTracker.removeBusy(file);
0451:	return body;	
0452:    }
0453:
0454:    public void put(final DAVTreeNode parentNode,
0455:		    final String fileName,
0456:		    final byte[] bodyBytes)
0457:    {
0458:	put(parentNode, fileName, bodyBytes, null);
0459:    }
0460:
0461:    public void put(final DAVTreeNode parentNode, 
0462:		    final String fileName, 
0463:		    final byte[] bodyBytes,
0464:		    final Runnable successRunner)
0465:    {
0466:	Assertion.assert((parentNode!=null), 
0467:			 "DAVTreeNode {0} is not null", 
0468:			 new Object[] {parentNode});
0469:	BusinessTracker.addBusy("put");
0470:	Thread t=new Thread() {
0471:		public void run()
0472:		{
0473:		    ConnectStruct cs=getConnectStruct(parentNode, fileName);
0474:		    String filePath=cs.getFilePath();
0475:		    PutMethod method=new PutMethod(filePath, bodyBytes);
0476:		    /* 
0477:		     * look for a locktoken on the target resource, if it exists
0478:		     * and we already know about it
0479:		     */
0480:		    DAVFile possibleTarget=null;
0481:		    for (Iterator it=parentNode.getDAVFile().children();it.hasNext();)
0482:		    {
0483:			DAVFile kidFile=(DAVFile) it.next();
0484:			if (kidFile.getFileName().equals(fileName))
0485:			{
0486:			    possibleTarget=kidFile;
0487:			    break;
0488:			}
0489:		    }
0490:		    if (possibleTarget!=null)
0491:		    {
0492:			if (possibleTarget.isCollection())
0493:			{
0494:			    //not allowed
0495:			    String title=ResourceManager.getMessage(ResourceManager.ERROR_DIALOG_TITLE);
0496:			    String message=ResourceManager.getMessage(ResourceManager.PUT_NOT_ALLOWED_MESSAGE);
0497:			    JOptionPane.showMessageDialog(Explorer.guessActiveExplorer(), 
0498:							  message,
0499:							  title,
0500:							  JOptionPane.ERROR_MESSAGE);
0501:			    BusinessTracker.removeBusy("put");
0502:			    return;
0503:			}
0504:			else if (possibleTarget.isLocked())
0505:			{
0506:			    method.setLockToken(possibleTarget.getExclusiveLockToken());
0507:			}
0508:		    }
0509:		    try
0510:		    {
0511:			cs.getDAVConnection().execute(method);
0512:			//check status
0513:			int status=method.getStatus();
0514:			Debug.trace(this , Debug.DP3, "status of response: "+status);
0515:			if (status>=400)
0516:			    handleStatusError(filePath, status, method.getResponseBody());
0517:			else
0518:			{
0519:			    reloadNode(parentNode);
0520:			    if (successRunner!=null)
0521:				SwingUtilities.invokeLater(successRunner);
0522:			    BusinessTracker.removeBusy("put");
0523:			}
0524:		    }
0525:		    catch (Exception davie)
0526:		    {
0527:			Debug.trace(this , Debug.DP2, davie);
0528:			handleConnectionError(davie, cs.getHost(), cs.getPort());
0529:		    }
0530:		}
0531:	    };
0532:	t.start();
0533:    }
0534:
0535:    public void lock(final DAVTreeNode parentNode, final DAVFile file, final String userInfo, final Runnable runnable)
0536:    {
0537:	Assertion.assert((parentNode!=null), 
0538:			 "DAVTreeNode {0} is not null", 
0539:			 new Object[] {parentNode});
0540:	BusinessTracker.addBusy("lock");
0541:	Thread t=new Thread() {
0542:		public void run() {
0543:		    ConnectStruct cs=getConnectStruct(parentNode, file.getFileName());
0544:		    String filePath=cs.getFilePath();
0545:		    LockMethod method=new LockMethod(filePath, userInfo);
0546:		    try
0547:		    {
0548:			cs.getDAVConnection().execute(method);
0549:			int status=method.getStatus();
0550:			if (status>=400)
0551:			    handleStatusError(filePath, status, method.getResponseBody());
0552:			else 
0553:			{
0554:			    reloadNode(parentNode);
0555:			    if (runnable!=null)
0556:			    {
0557:				SwingUtilities.invokeLater(runnable);
0558:			    }
0559:			    BusinessTracker.removeBusy("lock");
0560:			}
0561:		    }
0562:		    catch (Exception e)
0563:		    {
0564:			handleConnectionError(e, cs.getHost(), cs.getPort());
0565:		    }
0566:		}
0567:	    };
0568:	t.start();
0569:    }
0570:
0571:    public void proppatch(final DAVTreeNode parentNode, final DAVFile file, final Map propertyValueMap)
0572:    {
0573:	Assertion.assert((parentNode!=null), 
0574:			 "DAVTreeNode {0} is not null", 
0575:			 new Object[] {parentNode});
0576:	BusinessTracker.addBusy("proppatch");
0577:	Thread t=new Thread() {
0578:		public void run() {
0579:		    ConnectStruct cs=getConnectStruct(parentNode, file.getFileName());
0580:		    String filePath=cs.getFilePath();
0581:		    PropPatchMethod method=new PropPatchMethod(filePath);
0582:		    if (file.isExclusiveLocked())
0583:		    {
0584:			method.setLockToken(file.getExclusiveLockToken());
0585:		    }
0586:		    
0587:		    for (Iterator it=propertyValueMap.keySet().iterator();it.hasNext();)
0588:		    {
0589:			Object o=it.next();
0590:			Object val=propertyValueMap.get(o);
0591:			if (!(o instanceof  DAVProperty))
0592:			{
0593:			    BusinessTracker.removeAllBusy();
0594:			    throw new IllegalArgumentException("propertyValueMap must map DAVProperty objects "
0595:							       + "to Object values.  A null value indicates that "
0596:							       + "the property should be removed.");
0597:			}
0598:			if (val!=null)
0599:			{
0600:			    method.putProperty((DAVProperty) o, val);
0601:			}
0602:			else method.removeProperty((DAVProperty) o);
0603:		    }
0604:		    try
0605:		    {
0606:			cs.getDAVConnection().execute(method);
0607:			int status=method.getStatus();
0608:			if (status>=400)
0609:			    handleStatusError(filePath, status, method.getResponseBody());
0610:			else if (status==207) //multistatus
0611:			{
0612:			    //check response body of children
0613:			    DAVFile retFile = method.getDAVFile();
0614:			    Integer statusObj=retFile.getStatus();
0615:			    if (statusObj==null) 
0616:			    {
0617:				Debug.trace(this , Debug.DP2, "null status for "+ retFile);
0618:			    }
0619:			    else
0620:			    {
0621:				status=statusObj.intValue();
0622:				if (status>=400)
0623:				{
0624:				    String s=retFile.getResponseDescription();
0625:				    if (s==null) s="";
0626:				    handleStatusError(retFile.getFullName(), 
0627:						      status, 
0628:						      s.getBytes());
0629:				    return;
0630:				}
0631:			    }
0632:			}
0633:			reloadNode(parentNode);
0634:			BusinessTracker.removeBusy("proppatch");
0635:		    }
0636:		    catch (Exception e)
0637:		    {
0638:			handleConnectionError(e, cs.getHost(), cs.getPort());
0639:		    }
0640:		}
0641:	    };
0642:	t.start();
0643:    }
0644:
0645:		    
0646:
0647:    public void stealLock(final DAVTreeNode parentNode, final DAVFile file, final String userInfo)
0648:    {
0649:	Assertion.assert((parentNode!=null), 
0650:			 "DAVTreeNode {0} is not null", 
0651:			 new Object[] {parentNode});
0652:	BusinessTracker.addBusy("steal");
0653:	Thread t=new Thread() {
0654:		public void run() {
0655:		    ConnectStruct cs=getConnectStruct(parentNode, file.getFileName());
0656:		    String filePath=cs.getFilePath();
0657:		    String lockToken=file.getExclusiveLockToken();
0658:		    Assertion.assert((lockToken!=null),
0659:				     "lockToken for {0} is not null",
0660:				     new Object[] {file});		    
0661:		    UnlockMethod unlockMethod=new UnlockMethod(filePath, lockToken);
0662:		    LockMethod lockMethod=new LockMethod(filePath, userInfo);
0663:		    try
0664:		    {
0665:			cs.getDAVConnection().execute(unlockMethod);
0666:			int status=unlockMethod.getStatus();
0667:			if (status>=400)
0668:			{
0669:			    if (status==403)
0670:			    {
0671:				//obtain server data for node; set its permitsLockStealing property
0672:				ServerData.getServer(((DAVTreeNode)getPathToRoot(parentNode)[1]).toString())
0673:				    .setPermitsLockStealing(false);	  
0674:			    }
0675:			    handleStatusError(filePath, status, unlockMethod.getResponseBody());
0676:			}
0677:			else 
0678:			{
0679:			    cs.getDAVConnection().execute(lockMethod);
0680:			    status=lockMethod.getStatus();
0681:			    if (status>=400)
0682:				handleStatusError(filePath, status, lockMethod.getResponseBody());
0683:			    else 
0684:			    {
0685:				reloadNode(parentNode);
0686:				BusinessTracker.removeBusy("steal");
0687:			    }
0688:			}
0689:		    }
0690:		    catch (Exception e)
0691:		    {
0692:			handleConnectionError(e, cs.getHost(), cs.getPort());
0693:		    }
0694:		}
0695:	    };
0696:	t.start();
0697:    }
0698:
0699:    public void unlock(final DAVTreeNode parentNode, final DAVFile file)
0700:    {
0701:	unlock(parentNode, file, null);
0702:    }
0703:
0704:    public void unlock(final DAVTreeNode parentNode, final DAVFile file, final Runnable successRunner)
0705:    {
0706:	Assertion.assert((parentNode!=null), 
0707:			 "DAVTreeNode {0} is not null", 
0708:			 new Object[] {parentNode});
0709:		    BusinessTracker.addBusy("unlock");
0710:	Thread t=new Thread() {
0711:		public void run() {
0712:		    ConnectStruct cs=getConnectStruct(parentNode, file.getFileName());
0713:		    String filePath=cs.getFilePath();
0714:		    String lockToken=file.getExclusiveLockToken();
0715:		    Assertion.assert((lockToken!=null),
0716:				     "lockToken for {0} is not null",
0717:				     new Object[] {file});		    
0718:		    UnlockMethod method=new UnlockMethod(filePath, lockToken);
0719:		    try
0720:		    {
0721:			cs.getDAVConnection().execute(method);
0722:			int status=method.getStatus();
0723:			if (status>=400)
0724:			    handleStatusError(filePath, status, method.getResponseBody());
0725:			else 
0726:			{
0727:			    reloadNode(parentNode);
0728:			    if (successRunner!=null) SwingUtilities.invokeLater(successRunner);
0729:			    BusinessTracker.removeBusy("unlock");
0730:			}
0731:		    }
0732:		    catch (Exception e)
0733:		    {
0734:			handleConnectionError(e, cs.getHost(), cs.getPort());
0735:		    }
0736:		}
0737:	    };
0738:	t.start();
0739:    }
0740:
0741:    public void delete(final DAVTreeNode parentNode, final String fileName)
0742:    {
0743:	Assertion.assert((parentNode!=null), 
0744:			 "DAVTreeNode {0} is not null", 
0745:			 new Object[] {parentNode});
0746:	BusinessTracker.addBusy("delete");
0747:	Thread t=new Thread() {
0748:		public void run() {
0749:		    ConnectStruct cs=getConnectStruct(parentNode, fileName);
0750:		    String filePath=cs.getFilePath();
0751:		    DeleteMethod method=new DeleteMethod(filePath);
0752:		    try
0753:		    {
0754:			cs.getDAVConnection().execute(method);
0755:			int status=method.getStatus();
0756:			if (status>=400)
0757:			    handleStatusError(filePath, status, method.getResponseBody());
0758:			else 
0759:			{
0760:			    reloadNode(parentNode);
0761:			    BusinessTracker.removeBusy("delete");
0762:			}
0763:		    }
0764:		    catch (Exception e)
0765:		    {
0766:			handleConnectionError(e, cs.getHost(), cs.getPort());
0767:		    }
0768:		}
0769:	    };
0770:	t.start();
0771:    }
0772: 
0773:    public void mkcol(final DAVTreeNode parentNode, final String collectionName)
0774:    {
0775:	Assertion.assert((parentNode!=null), 
0776:			 "DAVTreeNode {0} is not null", 
0777:			 new Object[] {parentNode});
0778:	BusinessTracker.addBusy("mkcol");
0779:	Thread t=new Thread() {
0780:		public void run()
0781:		{
0782:		    ConnectStruct cs=getConnectStruct(parentNode, collectionName);
0783:		    String filePath=cs.getFilePath();
0784:		    MkcolMethod method=new MkcolMethod(filePath);
0785:		    try
0786:		    {
0787:			cs.getDAVConnection().execute(method);
0788:			//check status
0789:			int status=method.getStatus();
0790:			Debug.trace(this , Debug.DP3, "status of response: "+status);
0791:			if (status>=400)
0792:			    handleStatusError(filePath, status, method.getResponseBody());
0793:			else 
0794:			{
0795:			    reloadNode(parentNode);
0796:			    BusinessTracker.removeBusy("mkcol");
0797:			}
0798:		    }
0799:		    catch (Exception davie)
0800:		    {
0801:			Debug.trace(this , Debug.DP2, davie);
0802:			handleConnectionError(davie, cs.getHost(), cs.getPort());
0803:		    }
0804:		}
0805:	    };
0806:	t.start();
0807:    } 
0808:
0809:    protected String getURLForPath(TreePath teepee)
0810:    {
0811:	Object[] path=teepee.getPath();
0812:	return _getURLForPath(path);
0813:    }
0814:
0815:    private String _getURLForPath(Object[] path)
0816:    {
0817:	if (path==null || path.length<2)
0818:	{
0819:	    return null;
0820:	}
0821:	String prefix=getProtocolForNode((DAVTreeNode)path[path.length-1]);
0822:	StringBuffer sb=new StringBuffer(prefix);
0823:	//discard root, which we don't show
0824:	for (int i=1;i<path.length;i++)
0825:	{
0826:	    if (i>1) sb.append(DAVConstants.DAV_FILE_SEPARATOR);
0827:	    sb.append(path[i]);
0828:	}
0829:	return sb.toString();
0830:    }
0831:
0832:    public DAVTreeNode getNodeMatchingPath(String path)
0833:    {
0834: 	if (path.startsWith(DAVConstants.DAV_FILE_SEPARATOR))
0835: 	    path=path.substring(1);
0836:	if (!path.endsWith(DAVConstants.DAV_FILE_SEPARATOR))
0837:	    path=path+DAVConstants.DAV_FILE_SEPARATOR;
0838:	return getNodeMatchingURL(path, getRoot(), false);
0839:    }
0840:
0841:    public DAVTreeNode getNodeMatchingURL(String url)
0842:    {
0843:	return getNodeMatchingURL(url, getRoot(), true);
0844:    }
0845:
0846:    protected DAVTreeNode getNodeMatchingURL(String url, Object nodeObj)
0847:    {
0848:	return getNodeMatchingURL(url, nodeObj, true);
0849:    }
0850:
0851:    private String getProtocolForNode(DAVTreeNode node)
0852:    {
0853:	if (node!=null)
0854:	    return node.getDAVFile().getDAVConnection().getProtocol();
0855:	return null;
0856:    }
0857:	
0858:
0859:    protected DAVTreeNode getNodeMatchingURL(String url, 
0860:					     Object nodeObj, 
0861:					     boolean useHttpPrefix)
0862:    {
0863:	String fullname=null;
0864:	if (nodeObj instanceof  DAVTreeNode)
0865:	{
0866:	    DAVTreeNode dtn=(DAVTreeNode) nodeObj;
0867:	    StringBuffer nameBuffer=new StringBuffer();
0868:	    if (useHttpPrefix)
0869:	    {
0870:		nameBuffer.append(getProtocolForNode(dtn))
0871:		    .append("://");
0872:	    }		
0873:	    fullname=nameBuffer.append(((DAVTreeNode)nodeObj).getDAVFile().getFullName()).toString();
0874:	    Debug.trace(this , Debug.DP5, "testing node with fullname {0} against url {1}",
0875:			new Object[] { fullname, url });
0876:	    if (url.equals(fullname))
0877:		return (DAVTreeNode)nodeObj;
0878:	}
0879:	if (nodeObj.equals(getRoot()) 
0880:	    || (fullname!=null && url.startsWith(fullname))) //recurse into directory
0881:	{
0882:	    int cnt=getChildCount(nodeObj);
0883:	    for (int i=0;i<cnt;i++)
0884:	    {
0885:		DAVTreeNode dtn=getNodeMatchingURL(url, getChild(nodeObj, i), useHttpPrefix);
0886:		if (dtn!=null)
0887:		    return dtn;
0888:	    }
0889:	}
0890:	return null;
0891:    }
0892:
0893:    private void copyOrMove(final DAVTreeNode node, 
0894:			    final DAVFile file, 
0895:			    final String destinationURL, 
0896:			    final boolean move)
0897:    {
0898:	Assertion.assert((node!=null), 
0899:			 "DAVTreeNode {0} is not null", 
0900:			 new Object[] {node});
0901:	BusinessTracker.addBusy("copyOrMove");
0902:	int fileDivider=destinationURL.lastIndexOf(DAVConstants.DAV_FILE_SEPARATOR)+1;
0903:	String destDir=destinationURL.substring(0, fileDivider);
0904:	String destFileName=destinationURL.substring(fileDivider);
0905:	Debug.trace(this , Debug.DP3, 
0906:		    "destination directory is {0}, destination filename is {1}", 
0907:		    new Object[] {destDir, destFileName});
0908:	DAVTreeNode destNode=getNodeMatchingURL(destDir, getRoot());
0909:	Debug.trace(this , Debug.DP3, "destNode: {0}",
0910:		    new Object[] {destNode});
0911:	if (destNode==null)
0912:	{
0913:	    Debug.trace(this , Debug.DP2, "destNode is null");
0914:	    //should throw or handle an error -- TO BE DONE
0915:	    BusinessTracker.removeBusy(this );
0916:	    return;
0917:	}
0918:	DAVFile possiblyLocked=null;
0919:	//see if the destination file already exists and has a lockToken
0920:	for (Iterator it=destNode.getDAVFile().children();it.hasNext();)
0921:	{
0922:	    DAVFile kidFile=(DAVFile) it.next();
0923:	    if (destFileName.equals(kidFile.getFileName()))
0924:	    {
0925:		possiblyLocked=kidFile;
0926:		Debug.trace(this , Debug.DP3, "possiblyLocked file: {0}",
0927:			    new Object[] {kidFile});
0928:		break;
0929:	    }
0930:	}
0931:
0932:	/*
0933:	 * at this point, check whether lock owner is same as current user;
0934:	 * if not, ??? TO BE DONE
0935:	 */
0936:	
0937:	final String destinationLockToken=(possiblyLocked!=null) 
0938:	    ? possiblyLocked.getExclusiveLockToken()
0939:	    : null;
0940:
0941:	Thread t=new Thread() {
0942:		public void run()
0943:		{
0944:		    ConnectStruct cs=getConnectStruct(node, file.getFileName());
0945:		    String filePath=cs.getFilePath();
0946:		    CopyMethod method=(move) 
0947:			? (new MoveMethod(filePath, destinationURL))
0948:			: (new CopyMethod(filePath, destinationURL));
0949:		    method.setSourceLockToken(file.getExclusiveLockToken());
0950:		    method.setDestLockToken(destinationLockToken);
0951:		    try
0952:		    {
0953:			cs.getDAVConnection().execute(method);
0954:			//check status
0955:			int status=method.getStatus();
0956:			Debug.trace(this , Debug.DP3, "status of response: "+status);
0957:			if (status>=400)
0958:			    handleStatusError(filePath, status, method.getResponseBody());
0959:			else 
0960:			{
0961:			    if (move) reloadNode(node);
0962:			    int lastDex=destinationURL.lastIndexOf(DAVConstants.DAV_FILE_SEPARATOR)+1;
0963:			    DAVTreeNode newNode=getNodeMatchingURL(destinationURL.substring(0, lastDex));
0964:			    reloadNode(newNode);
0965:			    BusinessTracker.removeBusy("copyOrMove");
0966:			}
0967:		    }
0968:		    catch (Exception davie)
0969:		    {
0970:			Debug.trace(this , Debug.DP2, davie);
0971:			handleConnectionError(davie, cs.getHost(), cs.getPort());
0972:		    }
0973:		}
0974:	    };
0975:	t.start();
0976:    }
0977:
0978:    public void copy(DAVTreeNode node, DAVFile file, String destinationURL)
0979:    {
0980:	copyOrMove(node, file, destinationURL, false);
0981:    }
0982:    
0983:
0984:    public void move(DAVTreeNode node, DAVFile file, String destinationURL)
0985:    {
0986:	copyOrMove(node, file, destinationURL, true);
0987:    }
0988:
0989:
0990:    protected void handleConnectionError(final Exception ugh, final String host, final int port)
0991:    {
0992:	Debug.trace(this , Debug.DP2, ugh);
0993:	Runnable r = new Runnable() {
0994:		public void run() {
0995:		    BusinessTracker.removeAllBusy();
0996:		    String message=ResourceManager
0997:			.getMessage(ResourceManager.CONNECTION_ERROR_MESSAGE, 
0998:				    new Object[] { host+DAVConstants.DAV_FILE_SEPARATOR+port, 
0999:						   ugh.getMessage() } );
1000:		    String title=ResourceManager.getMessage(ResourceManager.ERROR_DIALOG_TITLE);
1001:		    JOptionPane.showMessageDialog(Explorer.guessActiveExplorer(),
1002:						  message, 
1003:						  title,
1004:						  JOptionPane.ERROR_MESSAGE);
1005:		}
1006:	    };
1007:	if (SwingUtilities.isEventDispatchThread())
1008:	    r.run();
1009:	else SwingUtilities.invokeLater(r);
1010:    }
1011:
1012:    protected void handleStatusError(final String filePath, final int status, final byte[] bodyBytes)
1013:    {
1014:	Runnable r=new Runnable() {
1015:		public void run() {
1016:		    BusinessTracker.removeAllBusy();
1017:		    String title=ResourceManager.getMessage(ResourceManager.ERROR_DIALOG_TITLE);
1018:		    String message=ResourceManager.getMessage(ResourceManager.STATUS_ERROR_MESSAGE, 
1019:							      new Object[] {filePath, 
1020:									    new Integer(status), 
1021:									    new String(bodyBytes)});
1022:		    JOptionPane.showMessageDialog(Explorer.guessActiveExplorer(),
1023:						  message, 
1024:						  title,
1025:						  JOptionPane.ERROR_MESSAGE);
1026:		}
1027:	    };
1028:	if (SwingUtilities.isEventDispatchThread())
1029:	    r.run();
1030:	else SwingUtilities.invokeLater(r);
1031:    }
1032:
1033:    private void handleInvalidDestinationError(final String destination)
1034:    {
1035:	Runnable r=new Runnable() {
1036:		public void run() {
1037:		    BusinessTracker.removeAllBusy();
1038:		    String title=ResourceManager.getMessage(ResourceManager.ERROR_DIALOG_TITLE);
1039:		    String message=ResourceManager.getMessage(ResourceManager.INVALID_DESTINATION_ERROR_MESSAGE,
1040:							      new Object[] {destination});
1041:		    JOptionPane.showMessageDialog(Explorer.guessActiveExplorer(),
1042:						  message,
1043:						  title,
1044:						  JOptionPane.ERROR_MESSAGE);
1045:		}
1046:	    };
1047:	if (SwingUtilities.isEventDispatchThread())
1048:	    r.run();
1049:	else SwingUtilities.invokeLater(r);
1050:    }	
1051:
1052:    private ConnectStruct getConnectStruct(DAVTreeNode parentNode, String fileName)
1053:    {
1054:	DAVFile file=parentNode.getDAVFile();
1055:	String host=file.getHost();
1056:	int port=file.getPort();
1057:	String parentName=file.getName();
1058:	StringBuffer sb=new StringBuffer(parentName);
1059:	if (!parentName.endsWith(DAVConstants.DAV_FILE_SEPARATOR)) 
1060:	    sb.append(DAVConstants.DAV_FILE_SEPARATOR);
1061:	sb.append(fileName);
1062:	DAVConnection dc=DAVConnectionPool.getDAVConnection(host, port);
1063:	return new ConnectStruct(dc, sb.toString(), host, port);
1064:    }
1065:
1066:    private class ConnectStruct
1067:    {
1068:	private DAVConnection dc;
1069:	private String filePath;
1070:	private String host;
1071:	private int port;
1072:
1073:	public DAVConnection getDAVConnection() { return dc; }
1074:	public String getFilePath() { return filePath; }
1075:	public String getHost() { return host; }
1076:	public int getPort() { return port; }
1077:
1078:	ConnectStruct(DAVConnection dc, String filePath, String host, int port)
1079:	{
1080:	    this .dc=dc;
1081:	    this .filePath=filePath;
1082:	    this .host=host;
1083:	    this .port=port;
1084:	}
1085:    }
1086:}
1087:
1088:/* $Log: DAVTreeModel.java,v $
1089:/* Revision 1.34  2001/07/25 21:17:39  smulloni
1090:/* fixed typo in error message.
1091:/*
1092:/* Revision 1.33  2001/06/13 01:09:03  smulloni
1093:/* Some improvements to the network customizer (which is still buggy).
1094:/* Also improvements for using the doAllprop switch, and for the layout of
1095:/* the PropertiesDialog.
1096:/*
1097:/* Revision 1.32  2001/06/05 01:09:53  smulloni
1098:/* fixed bug wtih failed connection attempts, which used to set the
1099:/* connection flag as if the connection had succeeded.
1100:/*
1101:/* Revision 1.31  2001/01/23 20:50:09  smulloni
1102:/* added configurable socket timeout
1103:/*
1104:/* Revision 1.30  2001/01/05 08:01:12  smulloni
1105:/* changes to the connection gui for the Explorer; added depth configurability to
1106:/* propfind in the jpython test script; added an experimental "allprop" system
1107:/* property which affects the propfind query type
1108:/*
1109:/* Revision 1.29  2001/01/03 00:30:35  smulloni
1110:/* a number of modifications along the way to replacing JFileChooser with
1111:/* something more suitable for remote (virtual) files.
1112:/*
1113:/* Revision 1.28  2001/01/02 17:34:21  smulloni
1114:/* added the ability to create DAVTreeModels that show non-directories.  This
1115:/* permits me to use one with an org.skunk.swing.TreeNodeChooser.
1116:/*
1117:/* Revision 1.27  2000/12/19 22:36:05  smulloni
1118:/* adjustments to preamble.
1119:/*
1120:/* Revision 1.26  2000/12/18 23:22:47  smulloni
1121:/* added optional SSL capability to the gui application.  Separate make targets
1122:/* exist for building it will SSL support.
1123:/*
1124:/* Revision 1.25  2000/12/04 23:51:16  smulloni
1125:/* added ImageViewer; fixed word in SimpleTextEditor
1126:/*
1127:/* Revision 1.24  2000/12/03 23:53:26  smulloni
1128:/* added license and copyright preamble to java files.
1129:/*
1130:/* Revision 1.23  2000/11/28 19:36:19  smullyan
1131:/* some bug fixes; notes.
1132:/*
1133:/* Revision 1.22  2000/11/23 04:37:31  smullyan
1134:/* editor and explorer now synch their files using the StateMonitor, which has
1135:/* been improved significantly
1136:/*
1137:/* Revision 1.21  2000/11/22 00:11:26  smullyan
1138:/* editor now locks and unlocks, more or less appropriately.
1139:/*
1140:/* Revision 1.20  2000/11/20 23:30:19  smullyan
1141:/* more editor integration work.
1142:/*
1143:/* Revision 1.19  2000/11/17 20:25:04  smullyan
1144:/* new SaveAction; a StateMonitor being added to handle application state.
1145:/*
1146:/* Revision 1.18  2000/11/14 23:17:08  smullyan
1147:/* more improvements to the PropertiesDialog.
1148:/*
1149:/* Revision 1.17  2000/11/13 23:28:30  smullyan
1150:/* first pass at a gui for proppatch, added to the propertiese dialog.  Highly
1151:/* problematic still, needs substantial work.
1152:/*
1153:/* Revision 1.16  2000/11/10 22:40:06  smullyan
1154:/* added icon to table for resource type; fixes to copy and move; disabling of
1155:/* menu items that are inappropriate.
1156:/*
1157:/* Revision 1.15  2000/11/09 23:34:55  smullyan
1158:/* log added to every Java file, with the help of python.  Lock stealing
1159:/* implemented, and treatment of locks made more robust.
1160:/* */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.