Changeset 830


Ignore:
Timestamp:
06/20/09 18:35:26 (3 years ago)
Author:
jharrop
Message:

WIP (lightly tested so far) implementation of top-down LCS based heuristic for improving differencing performance

Location:
trunk/docx4j
Files:
3 added
20 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/docx4j/src/diffx/com/topologi/diffx/Main.java

    r824 r830  
    250250    diff(seq1, seq2, out, config); 
    251251  } 
     252   
     253  // NB: The signatures which takes Reader objects appear to be broken!! 
    252254 
    253255  /** 
     
    304306      throws DiffXException, IOException { 
    305307    SmartXMLFormatter formatter = new SmartXMLFormatter(out); 
    306     formatter.declarePrefixMapping(seq1.getPrefixMapping()); 
    307     formatter.declarePrefixMapping(seq2.getPrefixMapping()); 
     308    if (config != null) formatter.setConfig(config); 
    308309     
    309     if (config != null) formatter.setConfig(config); 
    310     SequenceSlicer slicer = new SequenceSlicer(seq1, seq2); 
    311     slicer.slice(); 
    312     slicer.formatStart(formatter); 
    313     DiffXAlgorithm df = new DiffXFitopsy(seq1, seq2); 
    314     df.process(formatter); 
    315     slicer.formatEnd(formatter); 
    316   } 
    317  
     310    diff(seq1, seq2, formatter, config); 
     311  } 
     312 
     313  public static void diff(EventSequence seq1, EventSequence seq2, SmartXMLFormatter formatter , DiffXConfig config) 
     314        throws DiffXException, IOException { 
     315            formatter.declarePrefixMapping(seq1.getPrefixMapping()); 
     316            formatter.declarePrefixMapping(seq2.getPrefixMapping()); 
     317             
     318            if (config != null) formatter.setConfig(config); 
     319            SequenceSlicer slicer = new SequenceSlicer(seq1, seq2); 
     320            slicer.slice(); 
     321            slicer.formatStart(formatter); 
     322            DiffXAlgorithm df = new DiffXFitopsy(seq1, seq2); 
     323            df.process(formatter); 
     324            slicer.formatEnd(formatter); 
     325  } 
     326   
    318327// command line -------------------------------------------------------------------------  
    319328 
  • trunk/docx4j/src/diffx/com/topologi/diffx/algorithm/DiffXFitopsy.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import com.topologi.diffx.Docx4jDriver; 
    108109import com.topologi.diffx.event.DiffXEvent; 
    109110import com.topologi.diffx.event.AttributeEvent; 
     
    227228    // handle the case when one of the two sequences is empty 
    228229    processEmpty(formatter); 
     230     
     231    Docx4jDriver.log("length first: " + this.length1); 
     232    Docx4jDriver.log("length second: " + this.length2); 
     233     
    229234    if (this.length1 == 0 || this.length2 == 0) return; 
    230     // calculate the LCS length to fill the matrix 
     235 
     236    // Phase I: calculate the LCS length to fill the matrix (slow for lengths in order of > 10^2) 
     237    long startTime = System.currentTimeMillis(); 
    231238    length(); 
     239    long endTime = System.currentTimeMillis(); 
     240    long duration = endTime - startTime; 
     241    Docx4jDriver.log("diffx LCS phase took: " + duration + " ms "); 
     242     
    232243    int i = 0; 
    233244    int j = 0; 
    234245    DiffXEvent e1 = sequence1.getEvent(i); 
    235246    DiffXEvent e2 = sequence2.getEvent(j); 
    236     // start walking the matrix 
     247     
     248     
     249    // Phase II: start walking the matrix (this should be quick) 
    237250    while (i < super.length1 && j < super.length2) { 
    238251      e1 = sequence1.getEvent(i); 
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/AttributeEventImpl.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import org.apache.commons.lang.builder.HashCodeBuilder; 
     109 
    108110import com.topologi.diffx.event.AttributeEvent; 
    109111import com.topologi.diffx.event.DiffXEvent; 
     
    173175   * @see java.lang.Object#hashCode() 
    174176   */ 
    175   public int hashCode() { 
    176     return this.name.hashCode() + this.value.hashCode(); 
    177   } 
     177//  public int hashCode() { 
     178//    return this.name.hashCode() + this.value.hashCode(); 
     179//  } 
     180 
     181  private int fHashCode;   
     182  @Override public int hashCode() { 
     183            if ( fHashCode == 0) { 
     184                  // you pick a hard-coded, randomly chosen, non-zero, odd number 
     185                  // ideally different for each class 
     186              fHashCode = new HashCodeBuilder(17, 37). 
     187                                                          append(this.name). 
     188                                                          append(this.value). 
     189                                                          toHashCode(); 
     190            } 
     191            return fHashCode; 
     192          }   
     193   
    178194 
    179195  /** 
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/AttributeEventNSImpl.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import org.apache.commons.lang.builder.HashCodeBuilder; 
     109 
    108110import com.topologi.diffx.event.AttributeEvent; 
    109111import com.topologi.diffx.event.DiffXEvent; 
     
    194196   * @see java.lang.Object#hashCode() 
    195197   */ 
    196   public int hashCode() { 
    197     return this.name.hashCode() + this.value.hashCode(); 
    198   } 
    199  
     198//  public int hashCode() { 
     199//    return this.name.hashCode() + this.value.hashCode(); 
     200//  } 
     201 
     202  private int fHashCode;   
     203  @Override public int hashCode() { 
     204            if ( fHashCode == 0) { 
     205                  // you pick a hard-coded, randomly chosen, non-zero, odd number 
     206                  // ideally different for each class 
     207              fHashCode = new HashCodeBuilder(17, 37). 
     208                                                          append(this.name). 
     209                                                          append(this.uri). 
     210                                                          append(this.value). 
     211                                                          toHashCode(); 
     212            } 
     213            return fHashCode; 
     214          }   
     215   
    200216  /** 
    201217   * Returns <code>true</code> if the event is a   
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/CharEvent.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import org.apache.commons.lang.builder.HashCodeBuilder; 
     109 
    108110import com.topologi.diffx.event.DiffXEvent; 
    109111import com.topologi.diffx.xml.XMLWriter; 
     
    135137   * @see com.topologi.diffx.event.impl.DiffXEventBase#hashCode() 
    136138   */ 
    137   public int hashCode() { 
    138     return c; 
    139   } 
     139//  public int hashCode() { 
     140//    return c; 
     141//  } 
    140142 
     143  private int fHashCode;   
     144  @Override public int hashCode() { 
     145            if ( fHashCode == 0) { 
     146                  // you pick a hard-coded, randomly chosen, non-zero, odd number 
     147                  // ideally different for each class 
     148              fHashCode = new HashCodeBuilder(17, 37). 
     149                                                          append(this.c). 
     150                                                          toHashCode(); 
     151            } 
     152            return fHashCode; 
     153          }   
     154   
     155   
    141156  /** 
    142157   * @see com.topologi.diffx.event.impl.DiffXEventBase#equals(com.topologi.diffx.event.DiffXEvent) 
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/DiffXEventBase.java

    r824 r830  
    133133   * @see java.lang.Object#hashCode() 
    134134   */ 
    135   public abstract int hashCode(); 
     135//  public abstract int hashCode(); 
    136136 
    137137  /** 
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/EventFactory.java

    r824 r830  
    11package com.topologi.diffx.event.impl; 
    22 
     3import com.topologi.diffx.Docx4jDriver; 
    34import com.topologi.diffx.event.AttributeEvent; 
    45import com.topologi.diffx.event.CloseElementEvent; 
     
    152153   */ 
    153154  public AttributeEvent makeAttribute(String uri, String localName, String qName, String value) { 
     155           
     156//      if (localName.equals("space")) { 
     157//              Docx4jDriver.log("space!"); 
     158//              Docx4jDriver.log(uri); 
     159//              Docx4jDriver.log(qName); 
     160//      }          
     161           
    154162    if (this.isNamespaceAware) { 
    155163      return new AttributeEventNSImpl("".equals(uri)? null : uri, localName, value); 
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/LineEvent.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import org.apache.commons.lang.builder.HashCodeBuilder; 
     109 
    108110import com.topologi.diffx.event.DiffXEvent; 
    109111import com.topologi.diffx.event.TextEvent; 
     
    154156   * @see java.lang.Object#hashCode() 
    155157   */ 
    156   public int hashCode() { 
    157     return this.characters.hashCode(); 
    158   } 
    159  
     158//  public int hashCode() { 
     159//    return this.characters.hashCode(); 
     160//  } 
     161 
     162  private int fHashCode;   
     163  @Override public int hashCode() { 
     164            if ( fHashCode == 0) { 
     165                  // you pick a hard-coded, randomly chosen, non-zero, odd number 
     166                  // ideally different for each class 
     167              fHashCode = new HashCodeBuilder(17, 37). 
     168                                                          append(this.characters). 
     169                                                          toHashCode(); 
     170            } 
     171            return fHashCode; 
     172          }   
     173   
     174   
    160175  /** 
    161176   * Returns <code>true</code> if the event is a character event and the content is equivalent.   
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/OpenElementEventImpl.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import org.apache.commons.lang.builder.HashCodeBuilder; 
     109 
    108110 
    109111import com.topologi.diffx.Constants; 
     
    159161   * @see java.lang.Object#hashCode() 
    160162   */ 
    161   public int hashCode() { 
    162     return this.name.hashCode(); 
    163   } 
    164  
     163//  public int hashCode() { 
     164//    return this.name.hashCode(); 
     165//  } 
     166 
     167  private int fHashCode;   
     168  @Override public int hashCode() { 
     169            if ( fHashCode == 0) { 
     170                  // you pick a hard-coded, randomly chosen, non-zero, odd number 
     171                  // ideally different for each class 
     172              fHashCode = new HashCodeBuilder(17, 37). 
     173                                                          append(this.name). 
     174                                                          toHashCode(); 
     175            } 
     176            return fHashCode; 
     177          }   
     178   
    165179  /** 
    166180   * Returns <code>true</code> if the event is a   
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/OpenElementEventNSImpl.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import javax.xml.parsers.DocumentBuilderFactory; 
     109 
     110import org.apache.commons.lang.builder.HashCodeBuilder; 
     111 
    108112 
    109113import com.topologi.diffx.Constants; 
     
    160164    if (name == null) 
    161165      throw new NullPointerException("Element must have a name."); 
     166        // that will happen if you forgot to setNamespaceAware(true) on your DocumentBuilderFactory 
    162167    this.uri = uri; 
    163168    this.name = name; 
     
    181186   * @see java.lang.Object#hashCode() 
    182187   */ 
    183   public int hashCode() { 
    184     return this.uri.hashCode() + this.name.hashCode(); 
    185   } 
    186  
     188//  public int hashCode() { 
     189//    return this.uri.hashCode() + this.name.hashCode(); 
     190//  } 
     191 
     192  private int fHashCode;   
     193  @Override public int hashCode() { 
     194            if ( fHashCode == 0) { 
     195                  // you pick a hard-coded, randomly chosen, non-zero, odd number 
     196                  // ideally different for each class 
     197              fHashCode = new HashCodeBuilder(17, 37). 
     198                                                          append(this.uri). 
     199                                                          append(this.name). 
     200                                                          toHashCode(); 
     201            } 
     202            return fHashCode; 
     203          }   
     204   
    187205  /** 
    188206   * Returns <code>true</code> if the event is a   
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/ProcessingInstructionEvent.java

    r824 r830  
    106106import java.io.IOException; 
    107107 
     108import org.apache.commons.lang.builder.HashCodeBuilder; 
     109 
    108110import com.topologi.diffx.event.DiffXEvent; 
    109111import com.topologi.diffx.xml.XMLWriter; 
     
    162164   * @see java.lang.Object#hashCode() 
    163165   */ 
    164   public int hashCode() { 
    165     return this.target.hashCode() + this.data.hashCode(); 
    166   } 
    167  
     166//  public int hashCode() { 
     167//    return this.target.hashCode() + this.data.hashCode(); 
     168//  } 
     169 
     170  private int fHashCode;   
     171  @Override public int hashCode() { 
     172            if ( fHashCode == 0) { 
     173                  // you pick a hard-coded, randomly chosen, non-zero, odd number 
     174                  // ideally different for each class 
     175              fHashCode = new HashCodeBuilder(17, 37). 
     176                                                          append(this.target). 
     177                                                          append(this.data). 
     178                                                          toHashCode(); 
     179            } 
     180            return fHashCode; 
     181          }   
     182   
    168183  /** 
    169184   * Returns <code>true</code> if the event is a   
  • trunk/docx4j/src/diffx/com/topologi/diffx/event/impl/XMLBranchEvent.java

    r824 r830  
    22 
    33import java.io.IOException; 
     4 
     5import org.apache.commons.lang.builder.HashCodeBuilder; 
    46 
    57import com.topologi.diffx.event.DiffXEvent; 
     
    3638  public XMLBranchEvent(DiffXEvent[] events) { 
    3739    this.branch = events; 
    38     int tmpHash = 0; 
    39     for (int i = 0; i < events.length; i++) 
    40       tmpHash += events[i].hashCode(); 
    41     this.hashCode = tmpHash; 
     40//    int tmpHash = 0; 
     41//    for (int i = 0; i < events.length; i++) 
     42//      tmpHash += events[i].hashCode(); 
     43//    this.hashCode = tmpHash; 
     44    hashCode = new HashCodeBuilder(17, 37). 
     45          append(events). 
     46          toHashCode(); 
    4247  } 
    4348 
  • trunk/docx4j/src/diffx/com/topologi/diffx/load/DOMRecorder.java

    r824 r830  
    126126import org.xml.sax.InputSource; 
    127127 
     128import com.topologi.diffx.Docx4jDriver; 
    128129import com.topologi.diffx.config.DiffXConfig; 
    129130import com.topologi.diffx.event.AttributeEvent; 
     
    459460    if ("http://www.w3.org/2000/xmlns/".equals(e.getURI())) { 
    460461         
     462        //Docx4jDriver.log("Encountered namespace declaration: " + e.getValue() ); 
     463         
    461464        // Trap/handle xmlns:xmlns="", 
    462465        // which JAXB seems to produce  
     
    465468        if (e.getName().equals("xmlns") && 
    466469                        e.getValue().equals("") ) { 
    467                 System.out.println("Ignoring xmlns:xmlns='' "); 
     470                Docx4jDriver.log("Ignoring xmlns:xmlns='' "); 
    468471                return; 
    469472        } 
  • trunk/docx4j/src/diffx/com/topologi/diffx/sequence/EventSequence.java

    r824 r830  
    104104 */ 
    105105 
     106import java.io.IOException; 
    106107import java.io.PrintWriter; 
    107108import java.util.ArrayList; 
     
    111112import java.util.NoSuchElementException; 
    112113 
     114import org.apache.commons.lang.builder.HashCodeBuilder; 
     115 
    113116import com.topologi.diffx.event.DiffXEvent; 
     117import com.topologi.diffx.format.DiffXFormatter; 
    114118 
    115119/** 
     
    126130// Class attributes --------------------------------------------------------------------------- 
    127131 
    128   /** 
     132/** 
    129133   * The prefix mapping for the elements in this sequence. 
    130134   */ 
     
    134138   * The sequence of events. 
    135139   */ 
    136   private final List sequence; 
     140  private final List<DiffXEvent> sequence; 
    137141 
    138142// Constructors ------------------------------------------------------------------------------- 
     
    142146   */ 
    143147  public EventSequence() { 
    144     this.sequence = new LinkedList(); 
     148    this.sequence = new LinkedList<DiffXEvent>(); 
    145149  } 
    146150   
     
    151155   */ 
    152156  public EventSequence(int size) { 
    153     this.sequence = new ArrayList(size); 
     157    this.sequence = new ArrayList<DiffXEvent>(size); 
    154158  } 
    155159 
     
    243247   * @see java.lang.Object#hashCode() 
    244248   */ 
    245   public int hashCode() { 
    246     return this.sequence.size(); 
    247   } 
    248  
    249   /** 
    250    * Returns <code>true</code> if the specified event sequence is the same as this one. 
    251    *  
    252    * @param seq The sequence of events to compare with this one. 
    253    *  
    254    * @return <code>true</code> if the specified event sequence is equal to this one; 
    255    *         <code>false</code> otherwise.  
    256    */ 
     249//  public int hashCode() { 
     250//    return this.sequence.size(); 
     251//  } 
     252   
     253 
     254  private int fHashCode; 
     255 
     256        public int hashCode() { 
     257                if (fHashCode == 0) { 
     258                        HashCodeBuilder builder = new HashCodeBuilder(); 
     259                        for (Iterator i = this.sequence.iterator(); i.hasNext();) { 
     260                                builder.append(i.next()); 
     261                        } 
     262                        fHashCode = builder.toHashCode(); 
     263                } 
     264                return fHashCode; 
     265        } 
     266 
     267  /** 
     268         * Returns <code>true</code> if the specified event sequence is the same 
     269         * as this one. 
     270         *  
     271         * @param seq 
     272         *            The sequence of events to compare with this one. 
     273         *  
     274         * @return <code>true</code> if the specified event sequence is equal to 
     275         *         this one; <code>false</code> otherwise. 
     276         */ 
    257277  public boolean equals(EventSequence seq) { 
    258278    if (seq == null) return false; 
     
    313333    w.flush(); 
    314334  } 
    315  
    316   /** 
    317    * Maps a uri to a prefix. 
    318    *  
    319    * @see PrefixMapping#add(String, String) 
    320    *  
    321    * @param uri    The namespace URI to map.  
    322    * @param prefix The prefix to use. 
    323    *  
    324    * @throws NullPointerException if the URI or prefix is <code>null</code> 
    325    */ 
     335   
     336  /** 
     337   * Send this entire EventSequence to the formatter. 
     338   * Used by Docx4jDriver 
     339   *  
     340 * @param formatter 
     341 * @throws NullPointerException 
     342 * @throws IOException 
     343 */ 
     344public void format(DiffXFormatter formatter) throws NullPointerException, 
     345                        IOException { 
     346                DiffXEvent x = null; 
     347                for (int i = 0; i < sequence.size(); i++) { 
     348                        x = (DiffXEvent) sequence.get(i); 
     349                        formatter.format(x); 
     350                } 
     351        }   
     352 
     353  /** 
     354         * Maps a uri to a prefix. 
     355         *  
     356         * @see PrefixMapping#add(String, String) 
     357         *  
     358         * @param uri 
     359         *            The namespace URI to map. 
     360         * @param prefix 
     361         *            The prefix to use. 
     362         *  
     363         * @throws NullPointerException 
     364         *             if the URI or prefix is <code>null</code> 
     365         */ 
    326366  public void mapPrefix(String uri, String prefix) throws NullPointerException { 
    327367    this.prefixMapping.add(uri, prefix); 
     
    336376    return this.prefixMapping; 
    337377  } 
    338  
     378     
    339379// Inner class -------------------------------------------------------------------------------- 
    340380 
  • trunk/docx4j/src/diffx/com/topologi/diffx/sequence/PrefixMapping.java

    r824 r830  
    4343  } 
    4444 
     45  public void add(PrefixMapping others) throws NullPointerException { 
     46 
     47                String key; 
     48                for (Enumeration e = others.mappings.keys(); e.hasMoreElements();) { 
     49                        key = (String) e.nextElement(); 
     50                        this.mappings.put(key, others.mappings.get(key)); 
     51                } 
     52        } 
     53   
    4554  /** 
    46   * Returns an enumeration of the namespace URIs used in this mapping. 
    47   *  
    48   * @return An enumeration of the namespace URIs used in this mapping. 
    49   */ 
     55        * Returns an enumeration of the namespace URIs used in this mapping. 
     56        *  
     57        * @return An enumeration of the namespace URIs used in this mapping. 
     58        */ 
    5059  public Enumeration getURIs() { 
    5160    return this.mappings.keys(); 
  • trunk/docx4j/src/diffx/com/topologi/diffx/xml/NSAwareXMLWriter.java

    r824 r830  
    111111import java.util.List; 
    112112 
     113import com.topologi.diffx.Docx4jDriver; 
    113114import com.topologi.diffx.event.AttributeEvent; 
    114115 
     
    594595    String prefix = (String)this.prefixMapping.get((uri != null)? uri : ""); 
    595596    if (prefix == null) { 
    596       //throw new UndeclaredNamespaceException(uri); 
    597          
    598         // Horrible temporary nasty hack 
    599         // TODO 
    600         //System.out.println("FIX ME - com.topologi.diffx.xml.NSAwareXMLWriter.getQName(NSAwareXMLWriter.java:599)");            
    601         return "xml:"+name;      
     597        if (uri.equals("http://www.w3.org/XML/1998/namespace")) { 
     598                // eg xml:space ..  
     599                // per the namespace recommendation, this namespace may, but need not, be declared 
     600                // It is bound by definition to ... 
     601                return "xml:"+name;                      
     602        } else { 
     603                Docx4jDriver.log("FIX ME - com.topologi.diffx.xml.NSAwareXMLWriter.getQName(null, " + name + ") @599)");         
     604                throw new UndeclaredNamespaceException(uri + " for " + name); 
     605        } 
    602606    } else if ("".equals(prefix)) { 
    603607        return name;             
     
    644648 
    645649  /** 
    646    * Restores the prefix mapping after clsing an element. 
     650   * Restores the prefix mapping after closing an element. 
    647651   *  
    648652   * <p>This costly operation need only to be done if the method 
    649653   * {@link NSAwareXMLWriter#setPrefixMapping(String, String)} have been used 
    650    * immediately before, therefor it should not happen often. 
     654   * immediately before, therefore it should not happen often. 
    651655   *  
    652656   * @param elt The element that had some new mappings. 
    653657   */ 
    654658  private void restorePrefixMapping(Element elt) { 
    655     if (elt.mappings != null) { 
    656       // for each mapping of this element 
    657       for (int i = 0; i < elt.mappings.size(); i++) { 
    658         PrefixMapping mpi = (PrefixMapping)elt.mappings.get(i); 
    659         if (DEBUG) System.err.print(mpi.prefix+" -< "); 
    660         // find the first previous namespace mapping amongst the parents 
    661         // that defines namespace mappings 
    662         for (int j = elements.size() - 1; j > 0; j--) { 
    663           if (((Element)this.elements.get(j)).mappings != null) { 
    664             List mps = ((Element)elements.get(j)).mappings; 
    665             // iterate through the define namespace mappings of the parent 
    666             for (int k = 0; k < mps.size(); k++) { 
    667               PrefixMapping mpk = (PrefixMapping)mps.get(k); 
    668               // if we found a namespace prefix for the namespace 
    669               if (mpk.prefix.equals(mpi.prefix)) { 
    670                 removeIfNeeded(mpk.prefix); 
    671                 this.prefixMapping.put(mpk.uri, mpk.prefix); 
    672                 if (DEBUG) System.err.println(mpk.uri+" [R]"); 
    673                 j = 0; // exit from the previous loop 
    674                 break; // exit from this one 
    675               } 
    676             } 
    677           } 
    678         } 
    679       } 
    680     } 
    681   } 
    682  
    683   /** 
    684    * Removes the mapping associated to the specified prefix. 
    685    *  
    686    * @param prefix The prefix which mapping should be removed.  
    687    */ 
     659                if (elt.mappings != null) { 
     660                        // for each mapping of this element 
     661                        for (int i = 0; i < elt.mappings.size(); i++) { 
     662                                PrefixMapping mpi = (PrefixMapping) elt.mappings.get(i); 
     663                                if (DEBUG) 
     664                                        System.err.print(mpi.prefix + " -< "); 
     665                                // find the first previous namespace mapping amongst the parents 
     666                                // that defines namespace mappings 
     667                                for (int j = elements.size() - 1; j > 0; j--) { 
     668                                        if (((Element) this.elements.get(j)).mappings != null) { 
     669                                                List mps = ((Element) elements.get(j)).mappings; 
     670                                                // iterate through the define namespace mappings of the 
     671                                                // parent 
     672                                                for (int k = 0; k < mps.size(); k++) { 
     673                                                        PrefixMapping mpk = (PrefixMapping) mps.get(k); 
     674                                                        // if we found a namespace prefix for the namespace 
     675                                                        if (mpk.prefix.equals(mpi.prefix)) { 
     676                                                                removeIfNeeded(mpk.prefix); 
     677                                                                this.prefixMapping.put(mpk.uri, mpk.prefix); 
     678                                                                if (DEBUG) 
     679                                                                        System.err.println(mpk.uri + " [R]"); 
     680                                                                j = 0; // exit from the previous loop 
     681                                                                break; // exit from this one 
     682                                                        } 
     683                                                } 
     684                                        } 
     685                                } 
     686                        } 
     687                } 
     688        } 
     689 
     690  /** 
     691         * Removes the mapping associated to the specified prefix. 
     692         *  
     693         * @param prefix 
     694         *            The prefix which mapping should be removed. 
     695         */ 
    688696  private void removeIfNeeded(String prefix) { 
    689697    // remove the previous mapping to the prefix 
     
    696704      } 
    697705      this.prefixMapping.remove(key); // we know key should have a value 
     706          if (DEBUG) System.err.println("Removed " + prefix); 
     707       
    698708    } 
    699709  } 
  • trunk/docx4j/src/diffx/org/eclipse/compare/StringComparator.java

    r463 r830  
    11 
    2 package org.docx4j.diff; 
     2package org.eclipse.compare; 
    33 
    44import java.util.ArrayList; 
  • trunk/docx4j/src/main/java/org/docx4j/diff/MarkupDelete.xslt

    r820 r830  
    4444<xsl:param name="docPartRelsLeft"/> 
    4545<xsl:param name="docPartRelsRight"/> 
     46<xsl:param name="relsDiffIdentifier"/> 
    4647 
    4748  <xsl:output method="xml" encoding="utf-8" omit-xml-declaration="no" indent="yes" /> 
  • trunk/docx4j/src/main/java/org/docx4j/diff/MarkupInsert.xslt

    r820 r830  
    4444<xsl:param name="docPartRelsLeft"/> 
    4545<xsl:param name="docPartRelsRight"/> 
     46<xsl:param name="relsDiffIdentifier"/> 
    4647 
    4748<xsl:preserve-space elements="w:t"/>  
     
    107108    --> 
    108109     
    109 <xsl:template match="w:drawing" priority="5"> 
     110<xsl:template match="w:drawing" priority="3"> 
    110111   
    111112        <xsl:choose> 
     
    142143   
    143144  </xsl:template> 
    144        
    145      
     145           
    146146    <xsl:template match="a:blip"  priority="5"> 
    147147     
     
    325325   
    326326 
     327 
    327328</xsl:stylesheet> 
    328329 
  • trunk/docx4j/src/main/java/org/docx4j/diff/ParagraphDifferencer.java

    r814 r830  
    5656import org.docx4j.wml.R; 
    5757 
     58import org.eclipse.compare.StringComparator; 
    5859import org.eclipse.compare.rangedifferencer.RangeDifference; 
    59 import org.docx4j.diff.StringComparator; 
    6060import org.docx4j.jaxb.Context; 
    6161import org.docx4j.openpackaging.parts.relationships.RelationshipsPart; 
     
    6767import org.xml.sax.InputSource; 
    6868 
     69import com.topologi.diffx.Docx4jDriver; 
    6970import com.topologi.diffx.Main; 
    7071import com.topologi.diffx.config.DiffXConfig; 
     
    8485        protected static Logger log = Logger.getLogger(ParagraphDifferencer.class); 
    8586 
     87 
    8688        // For XSLT 
    8789        public static void log(String message ) {                
     
    9092         
    9193         
    92         public static Integer nextId = 0; 
    9394 
    9495        static org.docx4j.wml.ObjectFactory wmlFactory = new org.docx4j.wml.ObjectFactory(); 
     
    159160        } 
    160161         
    161         public final static Integer getId() { 
    162                  
    163                 return ++nextId; 
    164                  
    165         } 
    166          
     162        /** 
     163         * The id to be allocated to the ins/del 
     164         * @return 
     165         */ 
     166        public final static Integer getId() {            
     167                return ++nextId;                 
     168        } 
     169        public static Integer nextId = 0; 
     170 
     171         
     172        /** 
     173         * Because the resulting document might be built out of the  
     174         * results of a number of diffs, we need to be sure that the id's 
     175         * are unique across these diffs. 
     176         *  
     177         * This is passed into the XSLT, where it is used as part 
     178         * of the generated rel id. 
     179         *  
     180         * @return the  
     181         */ 
     182        private String relsDiffIdentifier;   
     183        /** 
     184         * @param relsDiffIdentifier the relsDiffIdentifier to set 
     185         */ 
     186        public void setRelsDiffIdentifier(String relsDiffIdentifier) { 
     187                this.relsDiffIdentifier = relsDiffIdentifier; 
     188        } 
     189 
    167190        /** 
    168191         * Any rel which is present in the results of the comparison must point to 
     
    171194         *  
    172195         * So we pass the old and new rels objects, and 
    173          * progressively build up a composite one. 
     196         * progressively build up a List of relationships which will need to be 
     197         * in the resulting document. 
     198         *  
     199         * Because the resulting document might be built out of the  
     200         * results of a number of diffs, we need to be sure that the id's 
     201         * are unique across these diffs. 
    174202         *  
    175203         * @return the  
     
    190218                } 
    191219                 
     220                 
     221                log.error("Looking for rel " + relId); 
    192222                Relationship r = docPartRels.getRelationshipByID(relId); 
    193223                if (r==null) { 
     
    199229                 
    200230                r2.setId(newRelId); 
     231                log.error(".. added rel " + newRelId + " -- " + r2.getTarget() ); 
    201232                 
    202233                pd.composedRels.add(r2); 
     
    221252        } 
    222253 
    223          
    224254        public void diff(org.docx4j.wml.SdtContentBlock cbLeft,  
    225255                        org.docx4j.wml.SdtContentBlock cbRight,  
     
    227257                        String author, java.util.Calendar date, 
    228258                        RelationshipsPart docPartRelsLeft, RelationshipsPart docPartRelsRight) { 
     259                 
     260                this.diffWorker(cbLeft, cbRight, result, author, date, docPartRelsLeft, docPartRelsRight); 
     261        } 
     262 
     263        public void diff(org.docx4j.wml.Body bodyLeft,  
     264                        org.docx4j.wml.Body bodyRight,  
     265                        javax.xml.transform.Result result, 
     266                        String author, java.util.Calendar date, 
     267                        RelationshipsPart docPartRelsLeft, RelationshipsPart docPartRelsRight) { 
     268                 
     269                this.diffWorker(bodyLeft, bodyRight, result, author, date, docPartRelsLeft, docPartRelsRight); 
     270        } 
     271         
     272        /** 
     273         * This is private, in order to control what objects the user 
     274         * can invoke diff on.  At present there are public methods for 
     275         * pairs of w:body, w:sdtContent, and w:p.   
     276         *  
     277         * TODO: consider/test w:table!  
     278         */ 
     279        private void diffWorker(Object objectLeft,  
     280                        Object objectRight,  
     281                        javax.xml.transform.Result result, 
     282                        String author, java.util.Calendar date, 
     283                        RelationshipsPart docPartRelsLeft, RelationshipsPart docPartRelsRight) { 
    229284 
    230285                Writer diffxResult = new StringWriter(); 
    231                  
    232                 DiffXConfig diffxConfig = new DiffXConfig(); 
    233                 diffxConfig.setIgnoreWhiteSpace(false); 
    234                 diffxConfig.setPreserveWhiteSpace(true); 
    235286 
    236287                try { 
    237                         Main.diff( org.docx4j.XmlUtils.marshaltoW3CDomDocument(cbLeft), 
    238                                            org.docx4j.XmlUtils.marshaltoW3CDomDocument(cbRight), 
    239                                            diffxResult, diffxConfig); 
     288                        Docx4jDriver.diff(org.docx4j.XmlUtils.marshaltoW3CDomDocument(objectLeft), 
     289                                           org.docx4j.XmlUtils.marshaltoW3CDomDocument(objectRight), 
     290                                           diffxResult); 
    240291                                // The signature which takes Reader objects appears to be broken 
    241292                        diffxResult.close(); 
     
    249300                        XMLInputFactory inputFactory = XMLInputFactory.newInstance(); 
    250301                        //java.io.InputStream is = new java.io.ByteArrayInputStream(naive.getBytes("UTF-8")); 
    251                         Reader reader = new StringReader(diffxResult.toString()); 
    252                          
    253                         String simplified = combineAdjacent(inputFactory.createXMLStreamReader(reader) ); 
     302                        Reader reader; 
     303//                      if (log.isDebugEnabled() ) { 
     304//                              String res = diffxResult.toString(); 
     305//                              log.debug(res); 
     306//                              reader = new StringReader(res); 
     307//                      } else { 
     308                                reader = new StringReader(diffxResult.toString());                               
     309//                      } 
     310                         
     311                        String simplified = null; 
     312                                try { 
     313                                        simplified = combineAdjacent(inputFactory.createXMLStreamReader(reader) ); 
     314                                } catch (XMLStreamException e) { 
     315                                        e.printStackTrace(); 
     316                                        log.debug("left: " + XmlUtils.marshaltoString(objectLeft, true, false)); 
     317                                        log.debug("right: " + XmlUtils.marshaltoString(objectRight, true, false));                                       
     318                                } 
    254319                         
    255320                        log.debug("\n\n Diff'd input to transform: \n\n" + simplified ); 
    256321                                                         
    257322                        StreamSource src = new StreamSource(new StringReader(simplified)); 
    258                         Map<String, Object> transformParameters = new java.util.HashMap<String, Object>(); 
    259                                                  
    260                         String dateString; 
    261                         if (date!=null) {                                
    262                                 dateString = RFC3339_FORMAT.format(date.getTime()) ; 
    263                         } else { 
    264                                 // TODO FIXME - JAXB requires a real date. 
    265                                 // What to give it?   
    266                                 // The alternative is to change the xslt 
    267                                 // to omit the @date entirely if its unknown 
    268                                 dateString = "2009-03-11T17:57:00Z"; 
    269                         } 
    270                         transformParameters.put("ParagraphDifferencer", this); 
    271                         transformParameters.put("date", dateString); 
    272                         transformParameters.put("author", author); 
    273                         transformParameters.put("docPartRelsLeft",  docPartRelsLeft); 
    274                         transformParameters.put("docPartRelsRight", docPartRelsRight); 
    275                          
    276                         XmlUtils.transform(src, xsltDiffx2Wml, transformParameters, result); 
     323                        transformDiffxOutputToWml(result, author, date, docPartRelsLeft, 
     324                                        docPartRelsRight, src); 
    277325                         
    278326                } catch (Exception exc) { 
     
    280328                }                        
    281329                 
     330        } 
     331 
     332        /** 
     333         * @param result 
     334         * @param author 
     335         * @param date 
     336         * @param docPartRelsLeft 
     337         * @param docPartRelsRight 
     338         * @param src 
     339         * @throws Exception 
     340         */ 
     341        private void transformDiffxOutputToWml(javax.xml.transform.Result result, 
     342                        String author, java.util.Calendar date, 
     343                        RelationshipsPart docPartRelsLeft, 
     344                        RelationshipsPart docPartRelsRight, StreamSource src) 
     345                        throws Exception { 
     346                Map<String, Object> transformParameters = new java.util.HashMap<String, Object>(); 
     347                                         
     348                String dateString; 
     349                if (date!=null) {                                
     350                        dateString = RFC3339_FORMAT.format(date.getTime()) ; 
     351                } else { 
     352                        // TODO FIXME - JAXB requires a real date. 
     353                        // What to give it?   
     354                        // The alternative is to change the xslt 
     355                        // to omit the @date entirely if its unknown 
     356                        dateString = "2009-03-11T17:57:00Z"; 
     357                } 
     358                transformParameters.put("ParagraphDifferencer", this); 
     359                transformParameters.put("date", dateString); 
     360                transformParameters.put("author", author); 
     361                transformParameters.put("docPartRelsLeft",  docPartRelsLeft); 
     362                transformParameters.put("docPartRelsRight", docPartRelsRight); 
     363                transformParameters.put("relsDiffIdentifier", relsDiffIdentifier);   
     364                 
     365                XmlUtils.transform(src, xsltDiffx2Wml, transformParameters, result); 
    282366        } 
    283367         
     
    310394                        transformParameters.put("docPartRelsLeft",  docPartRelsLeft); 
    311395                        transformParameters.put("docPartRelsRight", null); 
     396                        transformParameters.put("relsDiffIdentifier", relsDiffIdentifier);   
    312397                        XmlUtils.transform(doc, xsltMarkupInsert, transformParameters, result); 
    313398                         
     
    346431                        transformParameters.put("docPartRelsLeft",  null); 
    347432                        transformParameters.put("docPartRelsRight", docPartRelsRight); 
     433                        transformParameters.put("relsDiffIdentifier", relsDiffIdentifier);   
    348434                        XmlUtils.transform(doc, xsltMarkupDelete, transformParameters, result); 
    349435                         
     
    477563                                transformParameters.put("docPartRelsLeft",  docPartRelsLeft); 
    478564                                transformParameters.put("docPartRelsRight", docPartRelsRight); 
     565                                transformParameters.put("relsDiffIdentifier", relsDiffIdentifier);   
    479566                                XmlUtils.transform(src, xsltDiffx2Wml, transformParameters, result); 
    480567                                 
     
    707794                try { 
    708795                        StreamSource src = new StreamSource(new StringReader(diffx)); 
    709                         Map<String, Object> transformParameters = new java.util.HashMap<String, Object>(); 
    710                         transformParameters.put("ParagraphDifferencer", this); 
    711                         transformParameters.put("author", author); 
    712                         transformParameters.put("docPartRelsLeft",  docPartRelsLeft); 
    713                         transformParameters.put("docPartRelsRight", docPartRelsRight); 
    714                         XmlUtils.transform(src, xsltDiffx2Wml, transformParameters, result); 
    715                          
     796                        transformDiffxOutputToWml(result, author, date, docPartRelsLeft, 
     797                                        docPartRelsRight, src);                  
    716798                } catch (Exception exc) { 
    717799                        exc.printStackTrace(); 
  • trunk/docx4j/src/main/java/org/docx4j/diff/diffx2wml.xslt

    r823 r830  
    573573  </xsl:template> 
    574574 
    575   <xsl:template match="text()"> 
     575  <xsl:template match="text()[not(ancestor::wp:*)]"> 
    576576   
    577577      <w:r> 
Note: See TracChangeset for help on using the changeset viewer.