/** * Merges an existing annotation index into the currently-generated one. * * <p>This method is used to read previously-indexed annotations and reconcile them with the * newly-generated ones just. * * @param annotationName the name of the annotation for which the index contains the annotated * classes * @param factory the factory to generate input and output streams given an annotation name * @throws IOException */ protected synchronized void merge(final String annotationName, final StreamFactory factory) throws IOException { final InputStream in = factory.openInput(annotationName); if (in == null) { return; } Map<String, Object> map = this.map.get(annotationName); if (map == null) { map = new LinkedHashMap<String, Object>(); this.map.put(annotationName, map); } /* * To determine whether the index needs to be written out, * we need to keep track of changed entries. */ int changedCount = map.size(); boolean hasObsoletes = false; final IndexReader reader = new IndexReader(in); try { for (; ; ) { @SuppressWarnings("unchecked") final Map<String, Object> entry = (Map<String, Object>) reader.next(); if (entry == null) { break; } final String className = (String) entry.get("class"); if (factory.isClassObsolete(className)) { hasObsoletes = true; } else if (map.containsKey(className)) { if (!hasObsoletes && entry.equals(map.get(className))) { changedCount--; } } else { map.put(className, entry); } } } finally { reader.close(); } // if this annotation index is unchanged, no need to write it out again if (changedCount == 0 && !hasObsoletes) { this.map.remove(annotationName); } }
protected void destroyed(context c) { synchronized (lock) { if (current_context == c) { current_context = null; } } stream_factory.destroyed(c); }
protected synchronized void write(final StreamFactory factory) throws IOException { for (Entry<String, Map<String, Object>> entry : map.entrySet()) { final String annotationName = entry.getKey(); merge(annotationName, factory); final PrintStream out = new PrintStream(factory.openOutput(annotationName)); for (Object o : entry.getValue().values()) { writeObject(out, adapt(o)); } out.close(); } map.clear(); }