001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.citation; 031 032import java.lang.reflect.Method; 033import java.util.Collection; 034import java.util.LinkedHashSet; 035import java.util.Set; 036 037import org.openimaj.citation.annotation.Reference; 038import org.openimaj.citation.annotation.References; 039 040/** 041 * Listener that registers instances of {@link Reference} annotations. 042 * 043 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 044 */ 045public class ReferenceListener { 046 private static Set<Reference> references = new LinkedHashSet<Reference>(); 047 048 static { 049 addOpenIMAJReference(); 050 } 051 052 private static synchronized void addOpenIMAJReference() { 053 try { 054 final Class<?> clz = ReferenceListener.class.getClassLoader().loadClass("org.openimaj.OpenIMAJ"); 055 addReference(clz); 056 } catch (final ClassNotFoundException e) { 057 // assume that core-citation is being used outside OpenIMAJ 058 // and that thus you don't want/need an OI reference. 059 } 060 } 061 062 /** 063 * Register the given {@link Reference} 064 * 065 * @param r 066 * the {@link Reference} 067 */ 068 public static synchronized void addReference(Reference r) { 069 references.add(r); 070 } 071 072 /** 073 * Register the any {@link Reference} or {@link References} from the given 074 * class. 075 * 076 * @param clz 077 * the class 078 */ 079 public static void addReference(Class<?> clz) { 080 final Reference ann = clz.getAnnotation(Reference.class); 081 082 if (ann != null) 083 addReference(ann); 084 085 final References ann2 = clz.getAnnotation(References.class); 086 if (ann2 != null) 087 for (final Reference r : ann2.references()) 088 addReference(r); 089 090 processPackage(clz); 091 } 092 093 private static void processPackage(Class<?> clz) { 094 Package base = clz.getPackage(); 095 096 while (base != null) { 097 if (base.isAnnotationPresent(Reference.class)) 098 addReference(base.getAnnotation(Reference.class)); 099 100 if (base.isAnnotationPresent(References.class)) 101 for (final Reference r : base.getAnnotation(References.class).references()) 102 addReference(r); 103 104 final String name = base.getName(); 105 final int dot = name.lastIndexOf("."); 106 107 if (dot < 0) 108 break; 109 110 base = Package.getPackage(name.substring(0, dot)); 111 } 112 } 113 114 /** 115 * Register the any {@link Reference} or {@link References} from the given 116 * method. 117 * 118 * @param clz 119 * the class 120 * @param methodName 121 * @param signature 122 */ 123 public static void addReference(Class<?> clz, String methodName, String signature) { 124 for (final Method m : clz.getDeclaredMethods()) { 125 if (m.getName().equals(methodName) && m.toString().endsWith(signature)) { 126 final Reference ann = m.getAnnotation(Reference.class); 127 128 if (ann != null) 129 addReference(ann); 130 131 final References ann2 = m.getAnnotation(References.class); 132 if (ann2 != null) 133 for (final Reference r : ann2.references()) 134 addReference(r); 135 } 136 } 137 138 processPackage(clz); 139 } 140 141 /** 142 * Reset the references held by the listener, returning the current set of 143 * references. 144 * 145 * @return the current set of references. 146 */ 147 public static synchronized Set<Reference> reset() { 148 final Set<Reference> oldRefs = references; 149 references = new LinkedHashSet<Reference>(); 150 addOpenIMAJReference(); 151 return oldRefs; 152 } 153 154 /** 155 * Get a copy of the references collected by the listener 156 * 157 * @return the references. 158 */ 159 public static synchronized Set<Reference> getReferences() { 160 return new LinkedHashSet<Reference>(references); 161 } 162 163 /** 164 * Register the given {@link Reference}s 165 * 166 * @param refs 167 * the {@link Reference}s 168 */ 169 public static void addReferences(Collection<Reference> refs) { 170 references.addAll(refs); 171 } 172}