1 23 24 package org.hammurapi; 25 26 import java.text.ParseException ; 27 import java.text.SimpleDateFormat ; 28 import java.util.Collection ; 29 import java.util.Date ; 30 import java.util.HashSet ; 31 import java.util.Iterator ; 32 import java.util.LinkedList ; 33 import java.util.Set ; 34 35 import javax.xml.transform.TransformerException ; 36 37 import org.apache.oro.text.GlobCompiler; 38 import org.apache.oro.text.regex.MalformedPatternException; 39 import org.apache.oro.text.regex.Pattern; 40 import org.apache.oro.text.regex.Perl5Matcher; 41 import org.apache.xpath.CachedXPathAPI; 42 import org.w3c.dom.Element ; 43 import org.w3c.dom.Node ; 44 import org.w3c.dom.traversal.NodeIterator; 45 46 import com.pavelvlasov.jsel.CompilationUnit; 47 import com.pavelvlasov.jsel.JselException; 48 import com.pavelvlasov.jsel.LanguageElement; 49 import com.pavelvlasov.jsel.Operation; 50 import com.pavelvlasov.jsel.Package; 51 import com.pavelvlasov.jsel.TypeBody; 52 import com.pavelvlasov.review.Signed; 53 import com.pavelvlasov.xml.dom.AbstractDomObject; 54 55 59 public class DomWaiver extends AbstractDomObject implements Waiver { 60 private Set signatures=new HashSet (); 61 boolean active=true; 62 boolean hadSignatures=false; 63 64 private LinkedList elements=new LinkedList (); 65 66 private static class ElementEntry { 67 boolean exclude; 68 String name; 69 String operationSignature; 70 Pattern fileNamePattern; 71 } 72 73 77 private static void parseParameter(Object parameter, ElementEntry entry) { 78 String value = (String ) parameter; 79 int pi = value.indexOf('('); 80 if (pi==-1) { 81 entry.name=value; 82 } else { 83 int lastDot=value.lastIndexOf('.', pi); 84 if (lastDot==-1) { 85 entry.name="*"; 86 entry.operationSignature=value; 87 } else { 88 entry.name=value.substring(0, lastDot); 89 entry.operationSignature=value.substring(lastDot+1); 90 } 91 } 92 } 93 94 97 public DomWaiver(Element holder) throws HammurapiException { 98 super(); 99 try { 100 CachedXPathAPI cxpa=new CachedXPathAPI(); 101 inspectorName=getElementText(holder, "inspector-name", cxpa); 102 103 NodeIterator it=cxpa.selectNodeIterator(holder, "signature"); 104 Node signatureNode; 105 while ((signatureNode=it.nextNode())!=null) { 106 if (signatureNode instanceof Element ) { 107 hadSignatures=true; 108 signatures.add(getElementText(signatureNode)); 109 110 } 111 } 112 113 it=cxpa.selectNodeIterator(holder, "include-element|exclude-element|include-file|exclude-file"); 114 Element element; 115 while ((element=(Element ) it.nextNode())!=null) { 116 String elementText = getElementText(element); 117 if ("include-element".equals(element.getNodeName())) { 118 ElementEntry entry=new ElementEntry(); 119 entry.exclude=false; 120 parseParameter(elementText, entry); 121 elements.addFirst(entry); 122 } else if ("exclude-element".equals(element.getNodeName())) { 123 ElementEntry entry=new ElementEntry(); 124 entry.exclude=true; 125 parseParameter(elementText , entry); 126 elements.addFirst(entry); 127 } else if ("include-file".equals(element.getNodeName())) { 128 GlobCompiler compiler=new GlobCompiler(); 129 ElementEntry entry=new ElementEntry(); 130 entry.exclude=false; 131 try { 132 entry.fileNamePattern=compiler.compile(elementText); 133 } catch (MalformedPatternException e) { 134 throw new HammurapiException(e); 135 } 136 elements.addFirst(entry); 137 } else if ("exclude-file".equals(element.getNodeName())) { 138 GlobCompiler compiler=new GlobCompiler(); 139 ElementEntry entry=new ElementEntry(); 140 entry.exclude=true; 141 try { 142 entry.fileNamePattern=compiler.compile(elementText); 143 } catch (MalformedPatternException e) { 144 throw new HammurapiException(e); 145 } 146 elements.addFirst(entry); 147 } 148 } 149 150 reason=getElementText(holder, "reason", cxpa); 151 152 String expirationDateVal=getElementText(holder, "expiration-date", cxpa); 153 if (expirationDateVal!=null) { 154 SimpleDateFormat sdf=new SimpleDateFormat (DATE_FORMAT); 155 expirationDate=sdf.parse(expirationDateVal); 156 } 157 } catch (TransformerException e) { 158 throw new HammurapiException(e); 159 } catch (ParseException e) { 160 throw new HammurapiException(e); 161 } 162 } 163 164 private String inspectorName; 165 166 public String getInspectorName() { 167 return inspectorName; 168 } 169 170 private Date expirationDate; 171 172 public Date getExpirationDate() { 173 return expirationDate; 174 } 175 176 private String reason; 177 178 public String getReason() { 179 return reason; 180 } 181 182 public boolean waive(Violation violation, boolean peek) { 183 if (inspectorName.equals(violation.getDescriptor().getName())) { 184 if (hadSignatures) { 185 if (violation.getSource() instanceof Signed) { 186 String signature = ((Signed) violation.getSource()).getSignature(); 187 if (signatures.contains(signature)) { 188 if (!peek) { 189 signatures.remove(signature); 190 } 191 active=!signatures.isEmpty(); 192 return true; 193 } 194 } 195 } 196 197 if (elements.isEmpty()) { 198 return true; 199 } 200 201 if (violation.getSource() instanceof LanguageElement) { 202 for (LanguageElement element=(LanguageElement) violation.getSource(); element!=null; element=element.getParent()) { 203 if (_waive(element)) { 204 return true; 205 } 206 } 207 208 if (_waive(((LanguageElement) violation.getSource()).getCompilationUnit().getPackage())) { 209 return true; 210 } 211 } else if (violation.getSource() instanceof com.pavelvlasov.jsel.Package) { 212 if (_waive(violation.getSource())) { 213 return true; 214 } 215 } 216 } 217 return false; 218 } 219 220 private Perl5Matcher matcher=new Perl5Matcher(); 221 222 225 private boolean _waive(Object o) { 226 if (o instanceof Package ) { 227 Iterator it=elements.iterator(); 228 while (it.hasNext()) { 229 ElementEntry entry=(ElementEntry) it.next(); 230 Package pkg = (Package ) o; 231 if (entry.name!=null && entry.operationSignature==null && 232 ("*".equals(entry.name) 233 || pkg.getName().equals(entry.name) 234 || (entry.name.endsWith(".*") && pkg.getName().startsWith(entry.name.substring(0, entry.name.length()-2))))) { 235 return !entry.exclude; 236 } 237 } 238 } else if (o instanceof CompilationUnit) { 239 Iterator it=elements.iterator(); 240 while (it.hasNext()) { 241 ElementEntry entry=(ElementEntry) it.next(); 242 if (entry.fileNamePattern!=null && matcher.matches(((CompilationUnit) o).getName(), entry.fileNamePattern)) { 243 return !entry.exclude; 244 } 245 } 246 } else if (o instanceof TypeBody) { 247 Iterator it=elements.iterator(); 249 while (it.hasNext()) { 250 ElementEntry entry=(ElementEntry) it.next(); 251 try { 252 TypeBody typeBody = (TypeBody) o; 253 if (entry.name!=null && entry.operationSignature==null && typeBody.isKindOf(entry.name)) { 254 return !entry.exclude; 255 } 256 } catch (JselException e) { 257 if (!(e.getCause() instanceof ClassNotFoundException )) { 258 return false; 259 } 260 } 261 } 262 } else if (o instanceof Operation) { 263 Iterator it=elements.iterator(); 265 while (it.hasNext()) { 266 ElementEntry entry=(ElementEntry) it.next(); 267 try { 268 Operation operation = (Operation) o; 269 if (entry.name!=null && entry.operationSignature!=null && ("*".equals(entry.name) || operation.getEnclosingType().isKindOf(entry.name)) && operation.getInfo().isArgumentCompatible(entry.operationSignature)) { 270 return !entry.exclude; 271 } 272 } catch (JselException e) { 273 throw new HammurapiRuntimeException(e); 274 } 275 } 276 } 277 278 return false; 279 } 280 281 public boolean isActive() { 282 return active; 283 } 284 285 public Collection getSignatures() { 286 return signatures; 287 } 288 289 } 290 | Popular Tags |