View Javadoc
1 /* ==================================================================== 2 * The Apache Software License, Version 1.1 3 * 4 * Copyright (c) 2000 The Apache Software Foundation. All rights 5 * reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 18 * 19 * 3. The end-user documentation included with the redistribution, 20 * if any, must include the following acknowledgment: 21 * "This product includes software developed by the 22 * Apache Software Foundation (http://www.apache.org/)." 23 * Alternately, this acknowledgment may appear in the software itself, 24 * if and wherever such third-party acknowledgments normally appear. 25 * 26 * 4. The names "Apache" and "Apache Software Foundation" must 27 * not be used to endorse or promote products derived from this 28 * software without prior written permission. For written 29 * permission, please contact apache@apache.org. 30 * 31 * 5. Products derived from this software may not be called "Apache", 32 * nor may "Apache" appear in their name, without prior written 33 * permission of the Apache Software Foundation. 34 * 35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * SUCH DAMAGE. 47 * ==================================================================== 48 * 49 * This software consists of voluntary contributions made by many 50 * individuals on behalf of the Apache Software Foundation. For more 51 * information on the Apache Software Foundation, please see 52 * <http://www.apache.org/>. 53 * 54 * Portions of this software are based upon public domain software 55 * originally written at the National Center for Supercomputing Applications, 56 * University of Illinois, Urbana-Champaign. 57 */ 58 package com.bonevich.eclipse.cvsgrapher.model; 59 60 import org.apache.commons.logging.Log; 61 import org.apache.commons.logging.LogFactory; 62 import org.eclipse.core.runtime.IAdaptable; 63 import org.eclipse.team.internal.ccvs.core.CVSTag; 64 import org.eclipse.team.internal.ccvs.core.ILogEntry; 65 import org.eclipse.team.internal.ccvs.ui.VersionCollator; 66 67 import com.bonevich.eclipse.cvsgrapher.CvsGraphPlugin; 68 69 import java.util.*; 70 import java.util.regex.Matcher; 71 import java.util.regex.Pattern; 72 73 /*** 74 * The CVS Graph root, representing the reosurce being displayed. 75 * 76 * @author jbonevic 77 */ 78 public final class CvsGraphModel 79 { 80 private static final Log _logger = LogFactory.getLog(CvsGraphModel.class); 81 82 private static final String MAIN_BRANCH = "MAIN"; 83 84 private final List _entries; //elements: ILogEntry 85 86 private CvsGraphBranchModel _rootBranch; 87 private List _nodes = new ArrayList(); //elements: ICvsGraphEntryModel 88 private Map _sourceTagMap = new HashMap(); //elements: tag => CvsGraphNodeModel 89 private Map _mergeTagMap = new HashMap(); //elements: tag => CvsGraphNodeModel 90 91 public CvsGraphModel(ILogEntry[] entries) 92 { 93 _entries = Arrays.asList(entries); 94 Collections.sort(_entries, new LogEntrySorter()); 95 init(); 96 } 97 98 private void init() 99 { 100 ListIterator entries = _entries.listIterator(); 101 _rootBranch = createBranch("1", MAIN_BRANCH); 102 addEntry(_rootBranch, _rootBranch, entries); 103 104 createMergeConnections(); 105 } 106 107 private void createMergeConnections() 108 { 109 Iterator sourceTags = _sourceTagMap.keySet().iterator(); 110 while (sourceTags.hasNext()) 111 { 112 String sourceTag = (String) sourceTags.next(); 113 CvsGraphVersionModel sourceNode = (CvsGraphVersionModel) _sourceTagMap.get(sourceTag); 114 CvsGraphVersionModel mergeNode = (CvsGraphVersionModel) _mergeTagMap.get(sourceTag); 115 if (sourceNode != null && mergeNode != null && sourceNode != mergeNode) 116 { 117 createConnection(sourceNode, mergeNode, true); 118 } 119 } 120 } 121 122 private void addEntry(ICvsGraphNodeModel previous, CvsGraphBranchModel currentBranch, ListIterator entries) 123 { 124 if (_logger.isDebugEnabled()) 125 { 126 _logger.debug("adding entry = " + previous.getVersion()); 127 } 128 129 if (!entries.hasNext()) 130 { 131 return; 132 } 133 ILogEntry entry = (ILogEntry) entries.next(); 134 if (isBranchTerminus(currentBranch, entry)) 135 { 136 entries.previous(); 137 return; 138 } 139 previous = createVersion(previous, entry); 140 List branchTags = processTags(entry, previous); 141 if (branchTags != null) 142 { 143 int versionSuffix = 0; 144 Iterator tags = branchTags.iterator(); 145 while (tags.hasNext()) 146 { 147 versionSuffix += 2; 148 String version = previous.getVersion() + "." + versionSuffix; 149 addBranch(previous, entries, (String) tags.next(), version); 150 } 151 } 152 addEntry(previous, currentBranch, entries); 153 } 154 155 private void addBranch(ICvsGraphNodeModel previous, ListIterator entries, String tag, String version) 156 { 157 CvsGraphBranchModel branch = createBranch(version, tag); 158 previous.addChildNode(branch); 159 branch.setParent(previous); 160 161 if (_logger.isDebugEnabled()) 162 { 163 _logger.debug("adding branch = " + branch.getVersion()); 164 } 165 166 createConnection(previous, branch); 167 addEntry(branch, branch, entries); 168 } 169 170 private CvsGraphBranchModel createBranch(String version, String tag) 171 { 172 CvsGraphBranchModel branch = new CvsGraphBranchModel(version, tag); 173 _nodes.add(branch); 174 return branch; 175 } 176 177 private List processTags(ILogEntry entry, ICvsGraphNodeModel node) 178 { 179 List branchTags = null; 180 CVSTag[] tags = entry.getTags(); 181 if (tags.length > 0) 182 { 183 branchTags = new ArrayList(tags.length); 184 for (int j = 0; j < tags.length; j++) 185 { 186 String tag = tags[j].getName(); 187 if (tags[j].getType() == CVSTag.BRANCH) 188 { 189 // add in reverse order - earliest to most recent tag 190 branchTags.add(0, tag); 191 } 192 else 193 { 194 extractMergeTag(tag, node); 195 } 196 } 197 } 198 return branchTags; 199 } 200 201 private void extractMergeTag(String tag, ICvsGraphNodeModel node) 202 { 203 Pattern source = CvsGraphPlugin.getPlugin().getMergeTagSourcePreference(); 204 if (! extractMergeTag(tag, node, source, _sourceTagMap)) 205 { 206 Pattern dest = CvsGraphPlugin.getPlugin().getMergeTagDestPreference(); 207 extractMergeTag(tag, node, dest, _mergeTagMap); 208 } 209 } 210 211 private boolean extractMergeTag(String tag, ICvsGraphNodeModel node, Pattern pattern, Map tagMap) 212 { 213 Matcher matcher = pattern.matcher(tag); 214 if (matcher.find()) 215 { 216 tagMap.put(tag.substring(matcher.start(1), matcher.end(1)), node); 217 return true; 218 } 219 return false; 220 } 221 222 private CvsGraphVersionModel createVersion(ICvsGraphNodeModel previous, ILogEntry entry) 223 { 224 CvsGraphVersionModel node = new CvsGraphVersionModel(entry); 225 _nodes.add(node); 226 previous.addChildNode(node); 227 node.setParent(previous); 228 229 if (_logger.isDebugEnabled()) 230 { 231 _logger.debug("new node = " + node.getVersion()); 232 } 233 createConnection(previous, node); 234 235 if (_logger.isDebugEnabled()) 236 { 237 _logger.debug("connected to previous = " + previous.getVersion()); 238 } 239 return node; 240 } 241 242 private void createConnection(ICvsGraphNodeModel previous, ICvsGraphNodeModel node) 243 { 244 createConnection(previous, node, false); 245 } 246 247 private void createConnection(ICvsGraphNodeModel src, ICvsGraphNodeModel dest, boolean isMerge) 248 { 249 // if (isMerge) create different connection model 250 CvsGraphConnectionModel connection = new CvsGraphConnectionModel(isMerge); 251 252 connection.setSource(src); 253 connection.setTarget(dest); 254 255 src.addSourceConnection(connection); 256 dest.addTargetConnection(connection); 257 } 258 259 private boolean isBranchTerminus(CvsGraphBranchModel currentBranch, ILogEntry next) 260 { 261 String branchVersionPrefix = currentBranch.getVersion() + "."; 262 String nextVersion = next.getRevision(); 263 return (! nextVersion.startsWith(branchVersionPrefix)); 264 } 265 266 public List getNodes() 267 { 268 return _nodes; 269 } 270 271 public CvsGraphBranchModel getRootBranch() 272 { 273 return _rootBranch; 274 } 275 276 protected ILogEntry adaptToLogEntry(Object element) 277 { 278 // Get the log entry for the provided object 279 ILogEntry entry = null; 280 if (element instanceof ILogEntry) 281 { 282 entry = (ILogEntry) element; 283 } 284 else if (element instanceof IAdaptable) 285 { 286 entry = (ILogEntry) ((IAdaptable) element).getAdapter(ILogEntry.class); 287 } 288 return entry; 289 } 290 291 final class LogEntrySorter implements Comparator 292 { 293 private VersionCollator versionCollator = new VersionCollator(); 294 295 /*** 296 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object) 297 */ 298 public int compare(Object arg0, Object arg1) 299 { 300 ILogEntry e1 = adaptToLogEntry(arg0); 301 ILogEntry e2 = adaptToLogEntry(arg1); 302 303 return versionCollator.compare(e1.getRevision(), e2.getRevision()); 304 } 305 } 306 307 }

This page was automatically generated by Maven