1 package org.apache.maven.plugin.linkcheck.validation;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.InvalidClassException;
28 import java.io.ObjectInputStream;
29 import java.io.ObjectOutputStream;
30 import java.io.Serializable;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.LinkedList;
34 import java.util.List;
35 import java.util.Map;
36
37 /**
38 * @author <a href="mailto:bwalding@apache.org">Ben Walding</a>
39 * @author <a href="mailto:carlos@apache.org">Carlos Sanchez</a>
40 * @author <a href="mailto:aheritier@apache.org">Arnaud Heritier</a>
41 * @version $Id: LinkValidatorManager.java 532339 2007-04-25 12:28:56Z ltheussl $
42 */
43
44 public class LinkValidatorManager implements Serializable
45 {
46 /**
47 *
48 */
49 private static final long serialVersionUID = 2467928182206500945L;
50
51 /**
52 * Log for debug output
53 */
54 private static Log LOG = LogFactory.getLog( LinkValidatorManager.class );
55
56 private List validators = new LinkedList();
57
58 private String[] excludes = new String[0];
59
60 private Map cache = new HashMap();
61
62 public LinkValidatorManager()
63 {
64 }
65
66 public List getValidators()
67 {
68 return this.validators;
69 }
70
71 /**
72 * Returns the exclude.
73 *
74 * @return String
75 * @deprecated use getExcludes()
76 */
77 public String getExclude()
78 {
79 return this.excludes[0];
80 }
81
82 /**
83 * Sets the exclude.
84 *
85 * @param exclude
86 * The exclude to set
87 * @deprecated use setExcludes()
88 */
89 public void setExclude( String exclude )
90 {
91 this.excludes = new String[] { exclude };
92 }
93
94 /**
95 * Returns the excludes.
96 *
97 * @return String[]
98 */
99 public String[] getExcludes()
100 {
101 return this.excludes;
102 }
103
104 /**
105 * Sets the excludes.
106 *
107 * @param excludes
108 * The excludes to set
109 */
110 public void setExcludes( String[] excludes )
111 {
112 this.excludes = excludes;
113 }
114
115 public void addLinkValidator( LinkValidator lv )
116 {
117 this.validators.add( lv );
118 }
119
120 public LinkValidationResult validateLink( LinkValidationItem lvi ) throws Exception
121 {
122 {
123 LinkValidationResult status = getCachedResult( lvi );
124 if ( status != null )
125 {
126 return status;
127 }
128 }
129
130 for ( int i = 0; i < this.excludes.length; i++ )
131 {
132 if ( this.excludes[i] != null && lvi.getLink().startsWith( this.excludes[i] ) )
133 {
134 if ( LOG.isDebugEnabled() )
135 {
136 LOG.debug( "Excluded " + lvi.getLink() );
137 }
138 return new LinkValidationResult( LinkValidationResult.VALID, false, "" );
139 }
140 }
141 Iterator iter = this.validators.iterator();
142 LinkValidator lv;
143 Object resourceKey;
144 LinkValidationResult lvr;
145 while ( iter.hasNext() )
146 {
147 lv = (LinkValidator) iter.next();
148 resourceKey = lv.getResourceKey( lvi );
149 if ( resourceKey != null )
150 {
151 if ( LOG.isDebugEnabled() )
152 {
153 LOG.debug( lv.getClass().getName() + " - Checking link " + lvi.getLink() );
154 }
155 lvr = lv.validateLink( lvi );
156 if ( lvr.getStatus() == LinkValidationResult.NOTMINE )
157 {
158 continue;
159 }
160 setCachedResult( resourceKey, lvr );
161 return lvr;
162 }
163 }
164 lv = null;
165 resourceKey = null;
166 lvr = null;
167 LOG.error( "Unable to validate link : " + lvi.getLink() );
168 return new LinkValidationResult( LinkValidationResult.UNKNOWN, false, "No validator found for this link" );
169 }
170
171 public void loadCache( String cacheFilename )
172 {
173 try
174 {
175 File f = new File( cacheFilename );
176 if ( f.exists() )
177 {
178 ObjectInputStream is = new ObjectInputStream( new FileInputStream( cacheFilename ) );
179 this.cache = (Map) is.readObject();
180 is.close();
181 }
182 }
183 catch ( InvalidClassException e )
184 {
185 LOG.warn( "Your cache is incompatible with this new release of the plugin. It will be recreated." );
186 }
187 catch ( Throwable t )
188 {
189 LOG.error( "Unable to load the cache", t );
190 }
191 }
192
193 public void saveCache( String cacheFilename )
194 {
195 try
196 {
197
198 Map persistentCache = new HashMap();
199 Iterator iter = this.cache.keySet().iterator();
200 Object resourceKey;
201 while ( iter.hasNext() )
202 {
203 resourceKey = iter.next();
204 if ( ( (LinkValidationResult) this.cache.get( resourceKey ) ).isPersistent() )
205 {
206 persistentCache.put( resourceKey, this.cache.get( resourceKey ) );
207 if ( LOG.isDebugEnabled() )
208 {
209 LOG.debug( "[" + resourceKey + "] with result [" + this.cache.get( resourceKey )
210 + "] is stored in the cache." );
211 }
212 }
213 }
214 File cacheFile = new File( cacheFilename );
215 File dir = cacheFile.getParentFile();
216 if ( dir != null )
217 {
218 dir.mkdirs();
219 }
220 ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream( cacheFilename ) );
221 os.writeObject( persistentCache );
222 os.close();
223 persistentCache = null;
224 iter = null;
225 resourceKey = null;
226 cacheFile = null;
227 dir = null;
228 os = null;
229 }
230 catch ( Throwable t )
231 {
232 LOG.error( "Unable to save the cache", t );
233 }
234 }
235
236 /**
237 *
238 * @param lvi
239 * @return int Will return a status level, VALID, ERROR, UNKNOWN, WARNING
240 */
241 public LinkValidationResult getCachedResult( LinkValidationItem lvi )
242 {
243 Iterator iter = getValidators().iterator();
244 LinkValidator lv;
245 Object resourceKey;
246 while ( iter.hasNext() )
247 {
248 lv = (LinkValidator) iter.next();
249 resourceKey = lv.getResourceKey( lvi );
250 if ( resourceKey != null && this.cache.containsKey( resourceKey ) )
251 {
252 if ( LOG.isDebugEnabled() )
253 {
254 LOG.debug( "The cache returns for [" + resourceKey + "] the result [" + this.cache.get( resourceKey )
255 + "]." );
256 }
257 return (LinkValidationResult) this.cache.get( resourceKey );
258 }
259 }
260 lv = null;
261 resourceKey = null;
262 return null;
263 }
264
265 public void setCachedResult( Object resourceKey, LinkValidationResult lvr )
266 {
267 this.cache.put( resourceKey, lvr );
268 }
269 }