001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2012 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.duplications.detector.suffixtree;
021    
022    import java.util.List;
023    
024    import org.sonar.duplications.block.Block;
025    
026    import com.google.common.collect.Lists;
027    
028    /**
029     * Simplifies construction of <a href="http://en.wikipedia.org/wiki/Generalised_suffix_tree">generalised suffix-tree</a>.
030     */
031    public final class TextSet extends AbstractText {
032    
033      public static final class Builder {
034    
035        private List<Object> symbols = Lists.newArrayList();
036        private Integer lengthOfOrigin;
037        private int count;
038    
039        private Builder() {
040        }
041    
042        public void add(List<Block> list) {
043          symbols.addAll(list);
044          symbols.add(new Terminator(count));
045          count++;
046          if (lengthOfOrigin == null) {
047            lengthOfOrigin = symbols.size();
048          }
049        }
050    
051        public TextSet build() {
052          return new TextSet(symbols, lengthOfOrigin);
053        }
054    
055      }
056    
057      public static Builder builder() {
058        return new Builder();
059      }
060    
061      private final int lengthOfOrigin;
062    
063      private TextSet(List<Object> symbols, int lengthOfOrigin) {
064        super(symbols);
065        this.lengthOfOrigin = lengthOfOrigin;
066      }
067    
068      public boolean isInsideOrigin(int pos) {
069        return pos < lengthOfOrigin;
070      }
071    
072      @Override
073      public Object symbolAt(int index) {
074        Object obj = super.symbolAt(index);
075        if (obj instanceof Block) {
076          return ((Block) obj).getBlockHash();
077        }
078        return obj;
079      }
080    
081      public Block getBlock(int index) {
082        return (Block) super.symbolAt(index);
083      }
084    
085      public static class Terminator {
086    
087        private final int stringNumber;
088    
089        public Terminator(int i) {
090          this.stringNumber = i;
091        }
092    
093        @Override
094        public boolean equals(Object obj) {
095          return (obj instanceof Terminator) && (((Terminator) obj).stringNumber == stringNumber);
096        }
097    
098        @Override
099        public int hashCode() {
100          return stringNumber;
101        }
102    
103        public int getStringNumber() {
104          return stringNumber;
105        }
106    
107        @Override
108        public String toString() {
109          return "$" + stringNumber;
110        }
111    
112      }
113    
114    }