1 package org.codehaus.mojo.taglist.tags; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import java.util.ArrayList; 23 import java.util.Iterator; 24 import java.util.Locale; 25 26 import org.codehaus.mojo.taglist.beans.TagReport; 27 28 /** 29 * Class that define a classification of tags. 30 * <p> 31 * Each tag class contains 1 or more tags. This allows a user to define 32 * one tag "name" for display purposes, while still checking the files for 33 * multiple tag rules. 34 * <p> 35 * Example 36 * <pre> 37 * <tagClass> 38 * <displayName>Action Items</displayName> 39 * <tags> 40 * <tag> 41 * <matchString>todo</matchString> 42 * <matchType>ignoreCase</matchType> 43 * </tag> 44 * </tags> 45 * </tagClass> 46 * </pre> 47 * 48 */ 49 public class TagClass { 50 /** 51 * The tag class's name. 52 */ 53 private final String classDisplayName; 54 55 /** 56 * The tag report for this tag class. 57 */ 58 private final TagReport classTagReport; 59 60 /** 61 * The container of tags that make up this tag class. 62 */ 63 private final ArrayList<AbsTag> tags = new ArrayList<>(); 64 65 /** 66 * The int value for no tag match found. 67 */ 68 public static final int NO_MATCH = AbsTag.NO_MATCH; 69 70 /** 71 * The last tag to successfully match. 72 */ 73 private AbsTag lastSuccessfulTagMatch = null; 74 75 /** 76 * A unique ID counter for the tag classes. 77 */ 78 private static int uniqueTcCounter = 1; 79 80 /** 81 * Constructor. 82 * 83 * @param displayName the string to display as the name for this tag class. 84 */ 85 public TagClass(final String displayName) { 86 classDisplayName = displayName; 87 88 // Assign a unique ID for this tag class and update the global counter. 89 int uniqueId = uniqueTcCounter++; 90 91 classTagReport = new TagReport(displayName, "tag_class_" + uniqueId); 92 } 93 94 /** Access the tag report for this tag class. 95 * 96 * @return the tag class's tag report. 97 */ 98 public TagReport getTagReport() { 99 return (classTagReport); 100 } 101 102 /** Add a tag to this tag class. 103 * 104 * @param tag the tag to add to the tag class. 105 */ 106 public void addTag(AbsTag tag) { 107 if (tag != null) { 108 tags.add(tag); 109 110 classTagReport.addTagString(tag.tagString); 111 } 112 } 113 114 /** Get the index of the first tag contained from within a string. 115 * <p> 116 * The tag class will check each for its tags until a match is found 117 * within the specified string. If no match is found, this function will 118 * return TagClass.NO_MATCH for the index. 119 * 120 * @param currentLine the string for the current line being scanned. 121 * @param locale the Locale of the currentLine. 122 * @return the index within the string of the matched tag, or TagClass.NO_MATCH 123 * if not match was found. 124 */ 125 public int tagMatchContains(final String currentLine, final Locale locale) { 126 int index = NO_MATCH; 127 128 // Reset the last tag match 129 lastSuccessfulTagMatch = null; 130 131 for (AbsTag tag : tags) { 132 // Check if the string contain this tag 133 index = tag.contains(currentLine, locale); 134 135 if (index != NO_MATCH) { 136 // Store the last match 137 lastSuccessfulTagMatch = tag; 138 139 // Stop checking 140 break; 141 } 142 } 143 144 return index; 145 } 146 147 /** Check if a string starts with a tag from this tag class. 148 * <p> 149 * The tag class will check each of its tags until the start of the string 150 * matched one of the tags. If not match if found, false is returned. 151 * 152 * @param currentLine the string for the current line being scanned. 153 * @param locale the Locale of the currentLine. 154 * @return true if the string starts with a tag within this tag class. 155 * Otherwise false is returned. 156 */ 157 public boolean tagMatchStartsWith(final String currentLine, final Locale locale) { 158 boolean match = false; 159 160 Iterator<AbsTag> itr = tags.iterator(); 161 162 // Loop while there are more tags and there has not been a match. 163 while (itr.hasNext() && !match) { 164 AbsTag tag = itr.next(); 165 166 // Check if the string starts with this tag 167 match = tag.startsWith(currentLine, locale); 168 } 169 170 return match; 171 } 172 173 /** Return the tag string for the last successfully matched tag. 174 * 175 * @return string of the last matched tag. 176 */ 177 public String getLastTagMatchString() { 178 if (lastSuccessfulTagMatch == null) { 179 return (""); 180 } else { 181 return (lastSuccessfulTagMatch.tagString); 182 } 183 } 184 185 /** Return the length of the last matched tag. 186 * <p> 187 * Normally this is the length of the tag; however, some tags 188 * are dynamic. For example a regular expression tag might be 189 * 10 characters; however, the matched string may only be 5. 190 * <p> 191 * Calling this function allows the tag object to return the 192 * correct length for the last matched tag. 193 * 194 * @return the length of the last matched tag. 195 */ 196 public int getLastTagMatchStringLength() { 197 if (lastSuccessfulTagMatch == null) { 198 return (0); 199 } else { 200 return (lastSuccessfulTagMatch.getLastTagMatchLength()); 201 } 202 } 203 204 /** Get the display name of this tag class. 205 * 206 * @return the tag class display name. 207 */ 208 public String getDisplayName() { 209 return (classDisplayName); 210 } 211 }