1 19 20 package org.netbeans.modules.subversion.ui.browser; 21 22 import org.netbeans.modules.subversion.RepositoryFile; 23 import org.netbeans.modules.subversion.client.SvnProgressSupport; 24 import org.openide.nodes.AbstractNode; 25 import org.openide.nodes.Children; 26 import org.openide.nodes.Node; 27 import org.openide.util.RequestProcessor; 28 29 import javax.swing.*; 30 import java.util.Collections ; 31 import java.awt.*; 32 import java.beans.BeanInfo ; 33 import java.beans.PropertyEditor ; 34 import java.beans.PropertyEditorSupport ; 35 import java.lang.reflect.InvocationTargetException ; 36 import java.text.DateFormat ; 37 import java.util.Collection ; 38 import java.util.Date ; 39 import java.util.Iterator ; 40 import org.netbeans.modules.subversion.Subversion; 41 import org.netbeans.modules.subversion.ui.search.SvnSearch; 42 import org.openide.ErrorManager; 43 import org.openide.nodes.PropertySupport; 44 import org.openide.nodes.Sheet; 45 import org.tigris.subversion.svnclientadapter.SVNClientException; 46 import org.tigris.subversion.svnclientadapter.SVNNodeKind; 47 import org.tigris.subversion.svnclientadapter.SVNRevision; 48 import org.tigris.subversion.svnclientadapter.SVNUrl; 49 50 56 public class RepositoryPathNode extends AbstractNode { 57 58 private RepositoryPathEntry entry; 59 private final BrowserClient client; 60 private boolean repositoryFolder; 61 62 static class RepositoryPathEntry { 63 private final SVNNodeKind svnNodeKind; 64 private final RepositoryFile file; 65 private final SVNRevision revision; 66 private Date date; 67 private final String author; 68 RepositoryPathEntry (RepositoryFile file, SVNNodeKind svnNodeKind, SVNRevision revision, Date date, String author) { 69 this.svnNodeKind = svnNodeKind; 70 this.file = file; 71 this.revision =revision; 72 this.date = date; 73 this.author = author; 74 } 75 public SVNNodeKind getSvnNodeKind() { 76 return svnNodeKind; 77 } 78 RepositoryFile getRepositoryFile() { 79 return file; 80 } 81 SVNRevision getLastChangedRevision() { 82 return revision; 83 } 84 Date getLastChangedDate() { 85 return date; 86 } 87 String getLastChangedAuthor() { 88 return author; 89 } 90 } 91 92 static RepositoryPathNode createRepositoryPathNode(BrowserClient client, RepositoryFile file) { 93 return createRepositoryPathNode(client, new RepositoryPathEntry(file, SVNNodeKind.DIR, new SVNRevision(0), null, "")); 94 } 95 96 static RepositoryPathNode createRepositoryPathNode(BrowserClient client, RepositoryPathEntry entry) { 97 RepositoryPathChildren kids = new RepositoryPathChildren(client, entry); 98 RepositoryPathNode node = new RepositoryPathNode(kids, client, entry, true); 99 return node; 100 } 101 102 static RepositoryPathNode createBrowserPathNode(BrowserClient client, RepositoryPathEntry entry) { 103 RepositoryPathNode node = new RepositoryPathNode(new Children.Array(), client, entry, false); 104 return node; 105 } 106 107 private RepositoryPathNode(Children children, BrowserClient client, RepositoryPathEntry entry, boolean repositoryFolder) { 108 super(entry.getSvnNodeKind() == SVNNodeKind.DIR ? children : Children.LEAF); 109 this.entry = entry; 110 this.client = client; 111 this.repositoryFolder = repositoryFolder; 112 113 if(entry.getSvnNodeKind() == SVNNodeKind.DIR) { 114 setIconBaseWithExtension("org/openide/loaders/defaultFolder.gif"); } else { 116 setIconBaseWithExtension("org/openide/loaders/defaultFile.gif"); } 118 initProperties(); 119 } 120 121 private void initProperties() { 122 Sheet sheet = Sheet.createDefault(); 123 Sheet.Set ps = Sheet.createPropertiesSet(); 124 125 ps.put(new RevisionProperty()); 126 ps.put(new DateProperty()); 127 ps.put(new AuthorProperty()); 128 ps.put(new HistoryProperty()); 129 130 sheet.put(ps); 131 setSheet(sheet); 132 } 133 134 public String getDisplayName() { 135 return getName(); 136 } 137 138 public String getName() { 139 if(entry.getRepositoryFile().isRepositoryRoot()) { 140 return entry.getRepositoryFile().getRepositoryUrl().toString(); 141 } else { 142 return entry.getRepositoryFile().getName(); 143 } 144 } 145 146 public void setName(String name) { 147 String oldName = getName(); 148 if(!oldName.equals(name)) { 149 renameNode (this, name, 0); 150 this.fireNameChange(oldName, name); 151 } 152 } 153 154 private void renameNode (RepositoryPathNode node, String newParentsName, int level) { 155 node.entry = new RepositoryPathEntry( 156 node.entry.getRepositoryFile().replaceLastSegment(newParentsName, level), 157 node.entry.getSvnNodeKind(), 158 node.entry.getLastChangedRevision(), 159 node.entry.getLastChangedDate(), 160 node.entry.getLastChangedAuthor() 161 ); 162 Children childern = node.getChildren(); 163 Node[] childernNodes = childern.getNodes(); 164 level++; 165 for (int i = 0; i < childernNodes.length; i++) { 166 if(childernNodes[i] instanceof RepositoryPathNode) { 167 renameNode((RepositoryPathNode) childernNodes[i], newParentsName, level); 168 } 169 } 170 } 171 172 public Action[] getActions(boolean context) { 173 return client.getActions(); 174 } 175 176 public RepositoryPathEntry getEntry() { 177 return entry; 178 } 179 180 public BrowserClient getClient() { 181 return client; 182 } 183 184 public boolean canRename() { 185 return !repositoryFolder; 186 } 187 188 private void setRepositoryFolder(boolean bl) { 189 repositoryFolder = bl; 190 } 191 192 private static class RepositoryPathChildren extends Children.Keys { 193 194 private RequestProcessor.Task task; 195 196 private final RepositoryPathEntry pathEntry; 197 private final BrowserClient client; 198 199 public RepositoryPathChildren(BrowserClient client, RepositoryPathEntry pathEntry) { 200 this.client = client; 201 this.pathEntry = pathEntry; 202 } 203 204 protected void addNotify() { 205 super.addNotify(); 206 AbstractNode waitNode = new WaitNode(org.openide.util.NbBundle.getMessage(RepositoryPathNode.class, "BK2001")); setKeys(Collections.singleton(waitNode)); 208 listRepositoryPath(); 209 } 210 211 protected void removeNotify() { 212 task.cancel(); 213 setKeys(Collections.EMPTY_LIST); 214 super.removeNotify(); 215 } 216 217 protected Node[] createNodes(Object key) { 218 if (key instanceof Node) { 219 return new Node[] {(Node) key}; 220 } 221 222 RepositoryPathEntry entry = (RepositoryPathEntry) key; 223 Node node = this.findChild(entry.getRepositoryFile().getName()); 224 if(node != null) { 225 return null; 227 } 228 Node pathNode = RepositoryPathNode.createRepositoryPathNode(client, entry); 229 return new Node[] {pathNode}; 230 } 231 232 public void listRepositoryPath() { 233 RequestProcessor rp = Subversion.getInstance().getRequestProcessor(pathEntry.getRepositoryFile().getRepositoryUrl()); 234 SvnProgressSupport support = new SvnProgressSupport() { 235 public void perform() { 236 try { 237 Collection cl = client.listRepositoryPath(pathEntry, this); 238 if(cl == null) { 239 setKeys(Collections.EMPTY_LIST); 241 RepositoryPathNode node = (RepositoryPathNode) getNode(); 242 node.setRepositoryFolder(false); 243 } else { 244 if(!isCreativeBrowser(client)) { 245 removePreselectedFolders(cl); 246 } 247 setKeys(cl); 248 } 249 } catch (SVNClientException ex) { 250 setKeys(Collections.singleton(errorNode(ex))); 251 return; 252 } 253 } 254 }; 255 support.start(rp, pathEntry.getRepositoryFile().getRepositoryUrl(), org.openide.util.NbBundle.getMessage(Browser.class, "BK2001")); } 257 258 private String getLastPathSegment(RepositoryPathEntry entry) { 259 String [] childSegments = entry.getRepositoryFile().getPathSegments(); 260 return childSegments.length > 0 ? childSegments[childSegments.length-1] : null; 261 } 262 263 private static Node errorNode(Exception ex) { 264 AbstractNode errorNode = new AbstractNode(Children.LEAF); 265 errorNode.setDisplayName(org.openide.util.NbBundle.getMessage(RepositoryPathNode.class, "BK2002")); errorNode.setShortDescription(ex.getLocalizedMessage()); 267 return errorNode; 268 } 269 270 private boolean isCreativeBrowser(BrowserClient client) { 271 Action[] actions = client.getActions(); 272 for (int i = 0; i < actions.length; i++) { 273 if(actions[i] instanceof CreateFolderAction) { 274 return true; 275 } 276 } 277 return false; 278 } 279 280 private void removePreselectedFolders(final Collection cl) { 281 Node[] childNodes = getNodes(); 282 for(int i=0; i < childNodes.length; i++) { 283 if(childNodes[i] instanceof RepositoryPathNode) { 284 String lastChildSegment = getLastPathSegment( ((RepositoryPathNode) childNodes[i]).getEntry() ); 285 if(lastChildSegment!=null) { 286 boolean pathExists = false; 287 for(Iterator it = cl.iterator(); it.hasNext(); ) { 288 String lastNewChildSegment = getLastPathSegment((RepositoryPathEntry) it.next()); 289 if(lastNewChildSegment!=null) { 290 if(lastNewChildSegment.equals(lastChildSegment)) { 291 pathExists = true; 292 break; 293 } 294 } 295 } 296 if(!pathExists) { 297 remove(new Node[] { childNodes[i] }); 298 } 299 } 300 } 301 } 302 } 303 304 } 305 306 static final String PROPERTY_NAME_REVISION = "revision"; static final String PROPERTY_NAME_DATE = "date"; static final String PROPERTY_NAME_AUTHOR = "author"; static final String PROPERTY_NAME_HISTORY = "history"; 311 private final static String HISTORY_DISPLAY_NAME = org.openide.util.NbBundle.getMessage(RepositoryPathNode.class, "LBL_BrowserTree_History_Name"); 312 private final static String HISTORY_SHORT_DESC = org.openide.util.NbBundle.getMessage(RepositoryPathNode.class, "LBL_BrowserTree_History_Short_Desc"); 313 314 private class RevisionProperty extends NodeProperty { 315 316 public RevisionProperty() { 317 super(PROPERTY_NAME_REVISION, String .class, PROPERTY_NAME_REVISION, PROPERTY_NAME_REVISION); 318 } 319 320 public Object getValue() throws IllegalAccessException , InvocationTargetException { 321 return entry.getLastChangedRevision(); 322 } 323 } 324 325 private class DateProperty extends NodeProperty<String > { 326 327 public DateProperty() { 328 super(PROPERTY_NAME_DATE, String .class, PROPERTY_NAME_DATE, PROPERTY_NAME_DATE); 329 } 330 331 public String getValue() throws IllegalAccessException , InvocationTargetException { 332 Date date = entry.getLastChangedDate(); 333 return date != null ? DateFormat.getDateTimeInstance().format(date) : ""; 334 } 335 } 336 337 private class AuthorProperty extends NodeProperty<String > { 338 339 public AuthorProperty() { 340 super(PROPERTY_NAME_AUTHOR, String .class, PROPERTY_NAME_AUTHOR, PROPERTY_NAME_AUTHOR); 341 } 342 343 public String getValue() throws IllegalAccessException , InvocationTargetException { 344 return entry.getLastChangedAuthor(); 345 } 346 } 347 348 private class HistoryProperty extends PropertySupport.ReadOnly<String > { 349 350 public HistoryProperty() { 351 super(PROPERTY_NAME_HISTORY, String .class, HISTORY_DISPLAY_NAME, HISTORY_SHORT_DESC); 352 } 353 354 public String getValue() throws IllegalAccessException , InvocationTargetException { 355 return ""; 356 } 357 358 public String toString() { 359 try { 360 Object obj = getValue(); 361 return obj != null ? obj.toString() : ""; 362 } catch (Exception e) { 363 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 364 return e.getLocalizedMessage(); 365 } 366 } 367 368 public PropertyEditor getPropertyEditor() { 369 return new HistoryPropertyEditor(); 370 } 371 } 372 373 private abstract class NodeProperty<T> extends PropertySupport.ReadOnly<T> { 374 protected NodeProperty(String name, Class <T> type, String displayName, String shortDescription) { 375 super(name, type, displayName, shortDescription); 376 } 377 378 public String toString() { 379 try { 380 Object obj = getValue(); 381 return obj != null ? obj.toString() : ""; 382 } catch (Exception e) { 383 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 384 return e.getLocalizedMessage(); 385 } 386 } 387 388 public boolean canWrite() { 389 return false; 390 } 391 392 public PropertyEditor getPropertyEditor() { 393 return new PropertyEditorSupport (); 394 } 395 } 396 397 private class HistoryPropertyEditor extends PropertyEditorSupport { 398 399 public HistoryPropertyEditor() { 400 setValue(""); 401 } 402 403 public boolean supportsCustomEditor () { 404 return true; 405 } 406 407 public Component getCustomEditor() { 408 SVNRevision revision = entry.getLastChangedRevision(); 409 SVNUrl repositoryUrl = entry.getRepositoryFile().getRepositoryUrl(); 410 SVNUrl fileUrl = entry.getRepositoryFile().getFileUrl(); 411 final SvnSearch svnSearch = new SvnSearch(new RepositoryFile(repositoryUrl, fileUrl, revision)); 412 return svnSearch.getSearchPanel(); 413 } 414 } 415 416 } 417 | Popular Tags |