PageRenderTime 21ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/ide.kit/test/qa-functional/src/org/netbeans/test/ide/BlacklistedClassesHandlerSingleton.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 823 lines | 636 code | 67 blank | 120 comment | 110 complexity | 74056dd39abb199e5acee66f0c927303 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.test.ide;
  45. import java.io.BufferedInputStream;
  46. import java.io.BufferedOutputStream;
  47. import java.io.BufferedReader;
  48. import java.io.ByteArrayOutputStream;
  49. import java.io.File;
  50. import java.io.FileInputStream;
  51. import java.io.FileFilter;
  52. import java.io.FileNotFoundException;
  53. import java.io.FileOutputStream;
  54. import java.io.FileReader;
  55. import java.io.IOException;
  56. import java.io.PrintStream;
  57. import java.io.PrintWriter;
  58. import java.lang.management.ManagementFactory;
  59. import java.lang.management.ThreadInfo;
  60. import java.lang.management.ThreadMXBean;
  61. import java.lang.reflect.Method;
  62. import java.lang.reflect.Proxy;
  63. import java.util.ArrayList;
  64. import java.util.Collection;
  65. import java.util.Collections;
  66. import java.util.HashMap;
  67. import java.util.Iterator;
  68. import java.util.List;
  69. import java.util.Map;
  70. import java.util.Properties;
  71. import java.util.Set;
  72. import java.util.StringTokenizer;
  73. import java.util.TreeMap;
  74. import java.util.TreeSet;
  75. import java.util.logging.Handler;
  76. import java.util.logging.Level;
  77. import java.util.logging.LogRecord;
  78. import java.util.logging.Logger;
  79. import org.netbeans.modules.sampler.CustomSamplesStream;
  80. import org.openide.util.Exceptions;
  81. /**
  82. * BlacklistedClassesHandler performs processing of log messages to identify
  83. * which classes from a black list were loaded during application life cycle.
  84. *
  85. * The black list and the white list have to be specified in the separate text
  86. * files: each line is interpreted as classname, unless it is started with
  87. * non-identifier character. Leading and trailing spaces are ignored.
  88. *
  89. * Use getInstance and getBlacklistedClassesHandler methods to ensure that
  90. * only one instance of BlacklistedClassesHandlerSingleton is used across
  91. * the different classloaders
  92. *
  93. * @author nenik, mrkam@netbeans.org
  94. *
  95. */
  96. public class BlacklistedClassesHandlerSingleton extends Handler implements BlacklistedClassesHandler {
  97. private static final Logger PROXY_LOG = Logger.getLogger("org.netbeans.ProxyClassLoader"); // NOI18N
  98. private static final Logger LOG = Logger.getLogger(BlacklistedClassesHandlerSingleton.class.getName());
  99. private static BlacklistedClassesHandler instance = null;
  100. private int violation;
  101. // TODO: Is it necessary to use synchronizedMap? Should the list be synchronized?
  102. final private Map blacklist = Collections.synchronizedMap(new HashMap());
  103. final private Map whitelistViolators = Collections.synchronizedMap(new TreeMap());
  104. final private Set whitelist = Collections.synchronizedSortedSet(new TreeSet());
  105. final private Set previousWhitelist = Collections.synchronizedSortedSet(new TreeSet());
  106. final private Set newWhitelist = Collections.synchronizedSortedSet(new TreeSet());
  107. private boolean whitelistEnabled = false;
  108. private boolean generatingWhitelist = false;
  109. private String whitelistFileName;
  110. private boolean inited = false;
  111. private String newWhitelistFileName;
  112. private String previousWhitelistFileName = null;
  113. private File whitelistStorageDir = null;
  114. private CustomSamplesStream samples;
  115. private ThreadInfo lastThreadInfo;
  116. private ByteArrayOutputStream stream;
  117. private ThreadMXBean threadBean;
  118. private long start;
  119. private BlacklistedClassesHandlerSingleton() {
  120. }
  121. private BlacklistedClassesHandlerSingleton(String blacklistFileName) {
  122. this(blacklistFileName, null);
  123. }
  124. private BlacklistedClassesHandlerSingleton(String blacklistFileName, String whitelistFileName) {
  125. this(blacklistFileName, whitelistFileName, false);
  126. }
  127. private BlacklistedClassesHandlerSingleton(String blacklistFileName, String whitelistFileName, boolean generateWhitelist) {
  128. initSingleton(blacklistFileName, whitelistFileName, generateWhitelist);
  129. }
  130. public synchronized boolean initSingleton(String blacklistFileName, String whitelistFileName, boolean generateWhitelist) {
  131. return initSingleton(blacklistFileName, whitelistFileName, null, generateWhitelist);
  132. }
  133. public synchronized boolean initSingleton(String blacklistFileName, String whitelistFileName, String whitelistStorageDir, boolean generateWhitelist) {
  134. if (isInitialized()) {
  135. throw new Error("BlacklistedClassesHandler shouldn't be initialized twice!");
  136. }
  137. this.generatingWhitelist = generateWhitelist;
  138. this.whitelistFileName = whitelistFileName;
  139. new BlacklistedClassesViolationException("Dummy");
  140. if (whitelistStorageDir != null) {
  141. this.whitelistStorageDir = new File(whitelistStorageDir);
  142. this.whitelistStorageDir.mkdirs();
  143. try {
  144. newWhitelistFileName = new File(whitelistStorageDir, "whitelist" + System.currentTimeMillis() + ".txt").getCanonicalPath();
  145. } catch (IOException ex) {
  146. throw new RuntimeException(ex);
  147. }
  148. File[] files = this.whitelistStorageDir.listFiles(new FileFilter() {
  149. long lastModified = 0;
  150. public boolean accept(File pathname) {
  151. if (pathname.isFile() && pathname.getName().matches("whitelist.*\\.txt")) {
  152. return pathname.lastModified() >= lastModified;
  153. }
  154. return false;
  155. }
  156. });
  157. if (files.length > 0) {
  158. previousWhitelistFileName = files[files.length - 1].getPath();
  159. loadWhiteList(previousWhitelistFileName, previousWhitelist);
  160. }
  161. }
  162. threadBean = ManagementFactory.getThreadMXBean();
  163. start = System.currentTimeMillis();
  164. stream = new ByteArrayOutputStream();
  165. try {
  166. samples = new CustomSamplesStream(stream, 5000);
  167. } catch (IOException ex) {
  168. throw new RuntimeException(ex);
  169. }
  170. loadBlackList(blacklistFileName);
  171. loadWhiteList(this.whitelistFileName, whitelist);
  172. LOG.info(this.toString());
  173. LOG.info(
  174. blacklist.size() + " classes loaded to black list");
  175. if (this.whitelistEnabled) {
  176. LOG.info(
  177. whitelist.size() + " classes loaded to white list.");
  178. } else if (this.generatingWhitelist) {
  179. LOG.info(
  180. whitelist.size() + " classes loaded to white list. Whitelist is being generated.");
  181. } else {
  182. LOG.info(
  183. "White list disabled");
  184. }
  185. inited = true;
  186. return true;
  187. }
  188. public boolean initSingleton(String configFileName) {
  189. if (isInitialized()) {
  190. throw new Error("BlacklistedClassesHandler shouldn't be initialized twice!");
  191. }
  192. File configFile = new File(configFileName);
  193. Properties config = new Properties();
  194. try {
  195. config.loadFromXML(new BufferedInputStream(new FileInputStream(configFile)));
  196. } catch (FileNotFoundException fnfe) {
  197. LOG.severe(configFileName + " file not found.");
  198. return false;
  199. } catch (java.io.IOException ioe) {
  200. LOG.log(Level.SEVERE, "Failed to load " + configFileName, ioe);
  201. return false;
  202. }
  203. boolean configBlacklistEnabled = Boolean.parseBoolean(config.getProperty("blacklist.enabled"));
  204. boolean configWhitelistEnabled = Boolean.parseBoolean(config.getProperty("whitelist.enabled"));
  205. String configBlacklistFileName = configFile.getParent()
  206. + File.separator + config.getProperty("blacklist");
  207. String configWhitelistFileName = configFile.getParent()
  208. + File.separator + config.getProperty("whitelist");
  209. boolean configGenerateWhitelist = Boolean.parseBoolean(config.getProperty("generate.whitelist"));
  210. String configWhitelistStorageDir = config.getProperty("whitelist.storage.dir");
  211. boolean useWhitelistStorage = Boolean.parseBoolean(config.getProperty("use.whitelist.storage"));
  212. if (!configBlacklistEnabled) {
  213. configBlacklistFileName = null;
  214. }
  215. if (!configWhitelistEnabled) {
  216. configWhitelistFileName = null;
  217. }
  218. if (useWhitelistStorage && configWhitelistStorageDir == null) {
  219. configWhitelistStorageDir = System.getProperty("user.home") + File.separator + "whitelist_storage";
  220. } else {
  221. configWhitelistStorageDir = configFile.getParent() + File.separator + configWhitelistStorageDir;
  222. }
  223. if (configBlacklistEnabled || configWhitelistEnabled) {
  224. try {
  225. return initSingleton(configBlacklistFileName, configWhitelistFileName, configWhitelistStorageDir, configGenerateWhitelist);
  226. } catch (Exception ex) {
  227. LOG.log(Level.SEVERE,
  228. "Can't initialize BlacklistedClassesHandler due to the following exception:", ex);
  229. }
  230. }
  231. return false;
  232. }
  233. public boolean isInitialized() {
  234. return inited;
  235. }
  236. /**
  237. * Use this method to get existing instance of
  238. * BlacklistedClassesHandler. This method ensures that only one instance of
  239. * BlacklistedClassesHandler is shared across the different classloaders.
  240. *
  241. * @return existing instance of BlacklistedClassesHandler, null if there is
  242. * no such an instance
  243. */
  244. public static synchronized BlacklistedClassesHandler getBlacklistedClassesHandler() {
  245. getInstance();
  246. if (instance != null && instance.isInitialized()) {
  247. return instance;
  248. } else {
  249. return null;
  250. }
  251. }
  252. /**
  253. * Use this method to get existing or new non-initialized instance of
  254. * BlacklistedClassesHandler. This method ensures that only one instance of
  255. * BlacklistedClassesHandler is shared across the different classloaders.
  256. *
  257. * Use initSingleton methods to initialize BlacklistedClassesHandler
  258. * @return existing or new non-initialized instance of
  259. * BlacklistedClassesHandler
  260. */
  261. public static synchronized BlacklistedClassesHandler getInstance() {
  262. if (instance == null) {
  263. try {
  264. // TODO Is it really necessary to use proxies?
  265. ClassLoader myClassLoader = BlacklistedClassesHandlerSingleton.class.getClassLoader();
  266. ClassLoader parentClassLoader = ClassLoader.getSystemClassLoader();
  267. if (myClassLoader != parentClassLoader) {
  268. Class otherClassInstance = parentClassLoader.loadClass(BlacklistedClassesHandlerSingleton.class.getName());
  269. Method getInstanceMethod = otherClassInstance.getDeclaredMethod("getInstance", new Class[] { });
  270. Object otherAbsoluteSingleton = getInstanceMethod.invoke(null, new Object[] { } );
  271. instance = (BlacklistedClassesHandler) Proxy.newProxyInstance(myClassLoader,
  272. new Class[] { BlacklistedClassesHandler.class },
  273. new PassThroughProxyHandler(otherAbsoluteSingleton));
  274. } else {
  275. instance = new BlacklistedClassesHandlerSingleton();
  276. }
  277. } catch (Exception e) {
  278. throw new RuntimeException("Failed to get BlacklistedClassesHandler instance", e);
  279. }
  280. }
  281. return instance;
  282. }
  283. /**
  284. * Use this method to new initialized instance of
  285. * BlacklistedClassesHandler. This method ensures that only one instance of
  286. * BlacklistedClassesHandler is shared across the different classloaders.
  287. * And this instance must be initialized only once.
  288. * @param blacklistFileName if null blacklist checking is disabled
  289. * @return new initialized instance of BlacklistedClassesHandler. null if
  290. * initialization failed.
  291. */
  292. public static synchronized BlacklistedClassesHandler getBlacklistedClassesHandler(String blacklistFileName) {
  293. return getBlacklistedClassesHandler(blacklistFileName, null);
  294. }
  295. /**
  296. * Use this method to new initialized instance of
  297. * BlacklistedClassesHandler. This method ensures that only one instance of
  298. * BlacklistedClassesHandler is shared across the different classloaders.
  299. * And this instance must be initialized only once.
  300. * @param blacklistFileName if null blacklist checking is disabled
  301. * @param whitelistFileName if null whitelist checking is disabled
  302. * @return new initialized instance of BlacklistedClassesHandler. null if
  303. * initialization failed.
  304. */
  305. public static synchronized BlacklistedClassesHandler getBlacklistedClassesHandler(String blacklistFileName, String whitelistFileName) {
  306. return getBlacklistedClassesHandler(blacklistFileName, whitelistFileName, false);
  307. }
  308. /**
  309. * Use this method to new initialized instance of
  310. * BlacklistedClassesHandler. This method ensures that only one instance of
  311. * BlacklistedClassesHandler is shared across the different classloaders.
  312. * And this instance must be initialized only once.
  313. *
  314. * @param blacklistFileName if null blacklist checking is disabled
  315. * @param whitelistFileName if null whitelist checking is disabled
  316. * @param generateWhiteList if true whitelist checking is disabled. All
  317. * instantiated classes are added to the whitelist.
  318. * Use saveWhiteLists methods to save the list.
  319. * @return new initialized instance of BlacklistedClassesHandler. null if
  320. * initialization failed.
  321. */
  322. public static synchronized BlacklistedClassesHandler getBlacklistedClassesHandler(String blacklistFileName, String whitelistFileName, boolean generateWhiteList) {
  323. getInstance();
  324. if (instance.initSingleton(blacklistFileName, whitelistFileName, generateWhiteList)) {
  325. return instance;
  326. } else {
  327. return null;
  328. }
  329. }
  330. public void publish(LogRecord record) {
  331. // We can't use logging in this method as it could cause LinkageError
  332. try {
  333. if (record != null && record.getMessage() != null) {
  334. if (record.getMessage().contains("initiated")) {
  335. String className = (String) record.getParameters()[1];
  336. if (className.matches(".*\\$\\d+")) {
  337. return;
  338. }
  339. if (blacklist.containsKey(className)) { //violator
  340. Exception exc = new BlacklistedClassesViolationException(record.getParameters()[0].toString());
  341. // Check for AntProjectModule.checkForXalan() - fails on MacOSX
  342. boolean ignore = false;
  343. for (StackTraceElement elem : exc.getStackTrace()) {
  344. if ("checkForXalan".equals(elem.getMethodName()) &&
  345. (elem.getClassName().endsWith("AntProjectModule") ||
  346. elem.getClassName().endsWith("RakeProjectModule")))
  347. {
  348. ignore = true;
  349. break;
  350. }
  351. }
  352. if (!ignore) {
  353. System.out.println("BlacklistedClassesHandler blacklist violator: " + className);
  354. exc.printStackTrace();
  355. synchronized (blacklist) {
  356. // TODO: Probably we should synchronize by list
  357. ((List) blacklist.get(className)).add(exc);
  358. }
  359. violation++;
  360. }
  361. } else if (whitelistEnabled && !whitelist.contains(className)) {
  362. Exception exc = new BlacklistedClassesViolationException(record.getParameters()[0].toString());
  363. System.out.println("BlacklistedClassesHandler whitelist violator: " + className);
  364. exc.printStackTrace();
  365. synchronized (whitelistViolators) {
  366. // TODO: Probably we should synchronize by list
  367. if (whitelistViolators.containsKey(className)) {
  368. ((List) whitelistViolators.get(className)).add(exc);
  369. } else {
  370. List exceptions = new ArrayList();
  371. exceptions.add(exc);
  372. whitelistViolators.put(className, exceptions);
  373. violation++;
  374. ThreadInfo[] threads = threadBean.dumpAllThreads(false, false);
  375. for (ThreadInfo ti : threads) {
  376. if (ti.getThreadId() == Thread.currentThread().getId()) {
  377. StackTraceElement fakeEl = new StackTraceElement(className, "<loaded>", null, -1);
  378. ti.getStackTrace()[0] = fakeEl;
  379. samples.writeSample(new ThreadInfo[] {ti}, start*1000000L + violation * 10000000L, -1);
  380. lastThreadInfo = ti;
  381. break;
  382. }
  383. }
  384. }
  385. }
  386. } else if (generatingWhitelist) {
  387. whitelist.add(className);
  388. }
  389. newWhitelist.add(className);
  390. } else if (record.getMessage().equalsIgnoreCase("LIST BLACKLIST VIOLATIONS")) {
  391. logViolations();
  392. } else if (record.getMessage().equalsIgnoreCase("SAVE WHITELIST")) {
  393. saveWhiteList();
  394. }
  395. }
  396. } catch (Exception exc) {
  397. exc.printStackTrace();
  398. }
  399. }
  400. public void flush() {
  401. }
  402. public void close() throws SecurityException {
  403. /* Ugly hack to leave the handler when configuration is reset */
  404. PROXY_LOG.addHandler(this);
  405. PROXY_LOG.setLevel(Level.ALL);
  406. PROXY_LOG.setUseParentHandlers(false);
  407. }
  408. public void register() {
  409. PROXY_LOG.addHandler(this);
  410. PROXY_LOG.setLevel(Level.ALL);
  411. PROXY_LOG.setUseParentHandlers(false);
  412. System.setProperty("org.netbeans.ProxyClassLoader.level", "ALL"); // NOI18N
  413. }
  414. public void unregister() {
  415. PROXY_LOG.removeHandler(this);
  416. }
  417. public boolean noViolations() {
  418. return violation == 0;
  419. }
  420. public int getNumberOfViolations() {
  421. return violation;
  422. }
  423. public boolean noViolations(boolean listViolations) {
  424. if (violation > 0 && listViolations) {
  425. logViolations();
  426. }
  427. return violation == 0;
  428. }
  429. public boolean noViolations(PrintStream out) {
  430. if (violation > 0) {
  431. listViolations(out, true);
  432. }
  433. return violation == 0;
  434. }
  435. public void logViolations() {
  436. LOG.warning(listViolations());
  437. }
  438. /**
  439. * Returns only list of violators but prints all the exceptions to out
  440. * @param out
  441. * @return
  442. */
  443. public String reportViolations(PrintStream out) {
  444. return reportViolations(new PrintWriter(out));
  445. }
  446. public String reportViolations(PrintWriter out) {
  447. listViolationsAsXML(out, true);
  448. return listViolations(false, true);
  449. }
  450. public String listViolations() {
  451. return listViolations(true, true);
  452. }
  453. public String listViolations(boolean printCaptions) {
  454. return listViolations(printCaptions, printCaptions);
  455. }
  456. public String listViolations(boolean listExceptions, boolean printCaptions) {
  457. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  458. PrintStream ps = new PrintStream(baos);
  459. listViolations(ps, listExceptions, printCaptions);
  460. ps.flush();
  461. return baos.toString();
  462. }
  463. public void listViolations(PrintStream out, boolean printCaptions) {
  464. listViolations(out, false, printCaptions);
  465. }
  466. public void listViolations(PrintWriter out, boolean printCaptions) {
  467. listViolations(out, false, printCaptions);
  468. }
  469. public void listViolations(PrintStream out, boolean listExceptions, boolean printCaptions) {
  470. listViolations(new PrintWriter(out), listExceptions, printCaptions);
  471. }
  472. public void listViolations(PrintWriter out, boolean listExceptions, boolean printCaptions) {
  473. if (printCaptions) {
  474. out.println("BlacklistedClassesHandler identified the following violations:");
  475. }
  476. listViolationsMap("Blacklist violations:", blacklist, out, listExceptions, printCaptions);
  477. listViolationsMap("Whitelist violations:", whitelistViolators, out, listExceptions, printCaptions);
  478. out.flush();
  479. }
  480. public void listViolationsAsXML(PrintWriter out, boolean listExceptions) {
  481. out.println("<report>");
  482. listViolationsMapAsXML("blacklist", blacklist, out, listExceptions);
  483. listViolationsMapAsXML("whitelist", whitelistViolators, out, listExceptions);
  484. out.println("</report>");
  485. out.flush();
  486. }
  487. private void listViolationsMap(String caption, Map map, PrintWriter out, boolean listExceptions, boolean printCaptions) {
  488. long violationsCount = 0;
  489. if (printCaptions) {
  490. out.println(" " + caption);
  491. }
  492. synchronized (map) {
  493. final Set keySet = map.keySet();
  494. Iterator iter = keySet.iterator();
  495. while (iter.hasNext()) {
  496. String violator = (String) iter.next();
  497. if (((List) map.get(violator)).size() > 0) {
  498. violationsCount++;
  499. out.println(" " + violator);
  500. if (listExceptions) {
  501. final List exceptions = (List) map.get(violator);
  502. Iterator iter2 = exceptions.iterator();
  503. while (iter2.hasNext()) {
  504. Exception ex = (Exception) iter2.next();
  505. ex.printStackTrace(out);
  506. }
  507. }
  508. }
  509. }
  510. }
  511. if (printCaptions) {
  512. if (violationsCount > 0) {
  513. out.println(" Total: " + violationsCount + " violation(s).");
  514. } else {
  515. out.println(" No violations");
  516. }
  517. }
  518. }
  519. public String reportDifference() {
  520. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  521. PrintStream ps = new PrintStream(baos);
  522. reportDifference(ps);
  523. ps.flush();
  524. return baos.toString();
  525. }
  526. public void reportDifference(PrintStream out) {
  527. reportDifference(new PrintWriter(out));
  528. }
  529. public void reportDifference(PrintWriter out) {
  530. Set list = whitelist;
  531. String filename = whitelistFileName;
  532. if (previousWhitelistFileName != null) {
  533. list = previousWhitelist;
  534. filename = previousWhitelistFileName;
  535. }
  536. out.println("Diff between " + filename + " and " + newWhitelistFileName);
  537. out.println("+++ Added:");
  538. synchronized (list) {
  539. synchronized (newWhitelist) {
  540. int i = 0;
  541. Iterator iter = newWhitelist.iterator();
  542. while (iter.hasNext()) {
  543. String violator = (String) iter.next();
  544. if (!list.contains(violator)) {
  545. out.println(" " + violator);
  546. ++i;
  547. }
  548. }
  549. out.println(" Added " + i + " class(es)");
  550. out.println("--- Removed:");
  551. i = 0;
  552. iter = list.iterator();
  553. while (iter.hasNext()) {
  554. String violator = (String) iter.next();
  555. if (!newWhitelist.contains(violator)) {
  556. out.println(" " + violator);
  557. ++i;
  558. }
  559. }
  560. out.println(" Removed " + i + " class(es)");
  561. }
  562. }
  563. out.flush();
  564. }
  565. private void listViolationsMapAsXML(String caption, Map map, PrintWriter out, boolean listExceptions) {
  566. out.println(" <" + caption + ">");
  567. if (map.size() > 0) {
  568. out.println(" <violators>");
  569. synchronized (map) {
  570. int i = 0;
  571. final Set keySet = map.keySet();
  572. Iterator iter = keySet.iterator();
  573. while (iter.hasNext()) {
  574. String violator = (String) iter.next();
  575. if (((List) map.get(violator)).size() > 0) {
  576. out.println(" <violator class=\"" + violator + "\">");
  577. if (listExceptions) {
  578. final List exceptions = (List) map.get(violator);
  579. Iterator iter2 = exceptions.iterator();
  580. while (iter2.hasNext()) {
  581. BlacklistedClassesViolationException ex = (BlacklistedClassesViolationException) iter2.next();
  582. ex.printStackTraceAsXML(out);
  583. }
  584. }
  585. out.println(" </violator>");
  586. }
  587. }
  588. }
  589. out.println(" </violators>");
  590. } else {
  591. out.println(" <violators/>");
  592. }
  593. out.println(" </" + caption + ">");
  594. }
  595. public void resetViolations() {
  596. synchronized (blacklist) {
  597. final Set keySet = blacklist.keySet();
  598. Iterator iter = keySet.iterator();
  599. while (iter.hasNext()) {
  600. String violator = (String) iter.next();
  601. ((List) blacklist.get(violator)).clear();
  602. }
  603. violation = 0;
  604. }
  605. }
  606. private void loadBlackList(String blacklistFileName) {
  607. try {
  608. if (blacklistFileName != null) {
  609. Set<String> ts = new TreeSet<String>();
  610. readFile(new File(blacklistFileName), ts);
  611. for (String s : ts) {
  612. blacklist.put(s, new ArrayList());
  613. }
  614. }
  615. } catch (FileNotFoundException ex) {
  616. LOG.log(Level.SEVERE, null, ex);
  617. } catch (IOException ex) {
  618. LOG.log(Level.SEVERE, null, ex);
  619. }
  620. }
  621. private void loadWhiteList(String whitelistFileName, Set list) {
  622. try {
  623. if (whitelistFileName != null) {
  624. readFile(new File(whitelistFileName), list);
  625. if (!generatingWhitelist) {
  626. whitelistEnabled = true;
  627. }
  628. }
  629. } catch (FileNotFoundException ex) {
  630. LOG.log(Level.SEVERE, null, ex);
  631. } catch (IOException ex) {
  632. LOG.log(Level.SEVERE, null, ex);
  633. }
  634. }
  635. private static void readFile(
  636. File fn, Collection<String> res
  637. ) throws FileNotFoundException, IOException {
  638. BufferedReader reader = new BufferedReader(new FileReader(fn));
  639. final String INCLUDE = "#include ";
  640. try {
  641. for (String line = reader.readLine(); line != null; line = reader.readLine()) {
  642. line = line.trim();
  643. if (line.length() == 0) {
  644. continue;
  645. }
  646. if (line.startsWith(INCLUDE)) {
  647. File include = new File(fn.getParentFile(), line.substring(INCLUDE.length()));
  648. if (!include.isFile()) {
  649. throw new IOException("Cannot process " + line + "\nFile does not exist: " + include);
  650. }
  651. readFile(include, res);
  652. continue;
  653. }
  654. if (line.startsWith("#")) {
  655. continue;
  656. }
  657. res.add(line);
  658. }
  659. } finally {
  660. reader.close();
  661. }
  662. }
  663. public void saveWhiteList() {
  664. if (whitelistStorageDir != null) {
  665. saveWhiteList(newWhitelistFileName);
  666. } else {
  667. saveWhiteList(whitelistFileName);
  668. }
  669. }
  670. public void saveWhiteList(PrintStream out) {
  671. saveWhiteList(new PrintWriter(out));
  672. }
  673. public void saveWhiteList(String filename) {
  674. PrintStream ps = null;
  675. try {
  676. ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(filename)));
  677. saveWhiteList(ps);
  678. } catch (FileNotFoundException ex) {
  679. LOG.log(Level.SEVERE, null, ex);
  680. } finally {
  681. if (ps != null) {
  682. ps.flush();
  683. ps.close();
  684. }
  685. }
  686. }
  687. public void saveWhiteList(PrintWriter out) {
  688. synchronized (newWhitelist) {
  689. Iterator it = newWhitelist.iterator();
  690. while (it.hasNext()) {
  691. out.println(it.next());
  692. }
  693. }
  694. out.flush();
  695. }
  696. public boolean isGeneratingWhitelist() {
  697. return generatingWhitelist;
  698. }
  699. public boolean hasWhitelistStorage() {
  700. return whitelistStorageDir != null;
  701. }
  702. public void resetInitiated() {
  703. inited = false;
  704. resetViolations();
  705. whitelistViolators.clear();
  706. whitelist.clear();
  707. previousWhitelist.clear();
  708. newWhitelist.clear();
  709. whitelistEnabled = false;
  710. generatingWhitelist = false;
  711. }
  712. public void filterViolators(String[] list) {
  713. if (list!=null) {
  714. StringBuilder violat =new StringBuilder();
  715. final Set keySet = whitelistViolators.keySet();
  716. int count = list.length;
  717. Iterator iter = keySet.iterator();
  718. while (iter.hasNext()) {
  719. String violator = (String) iter.next();
  720. boolean filtered = true;
  721. for (int i = 0; i < count; i++) {
  722. if ( (violator.toLowerCase().contains(list[i])) ) {
  723. filtered = false;
  724. break;
  725. }
  726. }
  727. if (filtered) {
  728. violat.append(violator);
  729. violat.append(",");
  730. }
  731. }
  732. StringTokenizer tok = new StringTokenizer(violat.toString(), ",", false);
  733. while (tok.hasMoreTokens()) {
  734. whitelistViolators.remove(tok.nextToken());
  735. violation--;
  736. }
  737. }
  738. }
  739. @Override
  740. public void writeViolationsSnapshot(File file) {
  741. try {
  742. FileOutputStream fos = new FileOutputStream(file);
  743. if (lastThreadInfo != null) {
  744. samples.writeSample(new ThreadInfo[] {lastThreadInfo}, start*1000000L + (whitelistViolators.size()+1) * 10000000L, -1);
  745. }
  746. samples.close();
  747. fos.write(stream.toByteArray());
  748. fos.close();
  749. } catch (IOException ex) {
  750. Exceptions.printStackTrace(ex);
  751. } finally {
  752. lastThreadInfo = null;
  753. samples = null;
  754. }
  755. }
  756. }