001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2014 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube 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     * SonarQube 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 License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.api.batch.sensor.duplication;
021    
022    import org.apache.commons.lang.builder.EqualsBuilder;
023    import org.apache.commons.lang.builder.HashCodeBuilder;
024    import org.apache.commons.lang.builder.ToStringBuilder;
025    import org.apache.commons.lang.builder.ToStringStyle;
026    import org.sonar.api.batch.sensor.SensorContext;
027    
028    import java.util.ArrayList;
029    import java.util.List;
030    
031    /**
032     * A {@link DuplicationGroup} is a list of duplicated {@link Block}s. One block
033     * is considered as the original code and all others are duplicates.
034     * Use {@link SensorContext#duplicationBuilder(org.sonar.api.batch.fs.InputFile)} and
035     * {@link SensorContext#saveDuplications(org.sonar.api.batch.fs.InputFile, List)}.
036     * @since 4.5
037     */
038    public class DuplicationGroup {
039    
040      public static class Block {
041        private final String resourceKey;
042        private final int startLine;
043        private final int length;
044    
045        public Block(String resourceKey, int startLine, int length) {
046          this.resourceKey = resourceKey;
047          this.startLine = startLine;
048          this.length = length;
049        }
050    
051        public String resourceKey() {
052          return resourceKey;
053        }
054    
055        public int startLine() {
056          return startLine;
057        }
058    
059        public int length() {
060          return length;
061        }
062    
063        // Just for unit tests
064        @Override
065        public boolean equals(Object obj) {
066          if (obj == null) {
067            return false;
068          }
069          if (obj == this) {
070            return true;
071          }
072          if (obj.getClass() != getClass()) {
073            return false;
074          }
075          Block rhs = (Block) obj;
076          return new EqualsBuilder()
077            .append(resourceKey, rhs.resourceKey)
078            .append(startLine, rhs.startLine)
079            .append(length, rhs.length).isEquals();
080        }
081    
082        @Override
083        public int hashCode() {
084          return new HashCodeBuilder(13, 43)
085            .append(resourceKey)
086            .append(startLine)
087            .append(length).toHashCode();
088        }
089    
090        @Override
091        public String toString() {
092          return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).
093            append("resourceKey", resourceKey).
094            append("startLine", startLine).
095            append("length", length).
096            toString();
097        }
098      }
099    
100      private final Block originBlock;
101      private List<Block> duplicates = new ArrayList<DuplicationGroup.Block>();
102    
103      /**
104       * For unit test and internal use only.
105       */
106      public DuplicationGroup(Block originBlock) {
107        this.originBlock = originBlock;
108      }
109    
110      /**
111       * For unit test and internal use only.
112       */
113      public void setDuplicates(List<Block> duplicates) {
114        this.duplicates = duplicates;
115      }
116    
117      /**
118       * For unit test and internal use only.
119       */
120      public DuplicationGroup addDuplicate(Block anotherBlock) {
121        this.duplicates.add(anotherBlock);
122        return this;
123      }
124    
125      public Block originBlock() {
126        return originBlock;
127      }
128    
129      public List<Block> duplicates() {
130        return duplicates;
131      }
132    
133      // Just for unit tests
134      @Override
135      public boolean equals(Object obj) {
136        if (obj == null) {
137          return false;
138        }
139        if (obj == this) {
140          return true;
141        }
142        if (obj.getClass() != getClass()) {
143          return false;
144        }
145        DuplicationGroup rhs = (DuplicationGroup) obj;
146        EqualsBuilder equalsBuilder = new EqualsBuilder()
147          .append(originBlock, rhs.originBlock)
148          .append(duplicates.size(), rhs.duplicates.size());
149        if (duplicates.size() == rhs.duplicates.size()) {
150          for (int i = 0; i < duplicates.size(); i++) {
151            equalsBuilder.append(duplicates.get(i), rhs.duplicates.get(i));
152          }
153        }
154        return equalsBuilder.isEquals();
155      }
156    
157      @Override
158      public int hashCode() {
159        HashCodeBuilder hcBuilder = new HashCodeBuilder(17, 37)
160          .append(originBlock)
161          .append(duplicates.size());
162        for (int i = 0; i < duplicates.size(); i++) {
163          hcBuilder.append(duplicates.get(i));
164        }
165        return hcBuilder.toHashCode();
166      }
167    
168      @Override
169      public String toString() {
170        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).
171          append("origin", originBlock).
172          append("duplicates", duplicates, true).
173          toString();
174      }
175    
176    }