Clover Coverage Report
Coverage timestamp: Sa Aug 2 2008 13:56:27 CEST
../../../../../img/srcFileCovDistChart6.png 69% of files have more coverage
99   374   46   5,21
36   200   0,46   19
19     2,42  
1    
 
  DefaultModuleAddress       Line # 39 99 46 54,5% 0.54545456
 
  (46)
 
1    /* $Id: DefaultModuleAddress.java,v 1.1 2008/07/26 07:58:29 m31 Exp $
2    *
3    * This file is part of the project "Hilbert II" - http://www.qedeq.org
4    *
5    * Copyright 2000-2008, Michael Meyling <mime@qedeq.org>.
6    *
7    * "Hilbert II" is free software; you can redistribute
8    * it and/or modify it under the terms of the GNU General Public
9    * License as published by the Free Software Foundation; either
10    * version 2 of the License, or (at your option) any later version.
11    *
12    * This program is distributed in the hope that it will be useful,
13    * but WITHOUT ANY WARRANTY; without even the implied warranty of
14    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15    * GNU General Public License for more details.
16    */
17   
18    package org.qedeq.kernel.bo.service;
19   
20    import java.io.File;
21    import java.io.IOException;
22    import java.net.MalformedURLException;
23    import java.net.URL;
24   
25    import org.qedeq.base.io.IoUtility;
26    import org.qedeq.base.trace.Trace;
27    import org.qedeq.kernel.base.module.LocationList;
28    import org.qedeq.kernel.base.module.Specification;
29    import org.qedeq.kernel.common.ModuleAddress;
30    import org.qedeq.kernel.common.ModuleContext;
31   
32   
33    /**
34    * An object of this class represents an address for a QEDEQ module.
35    *
36    * @version $Revision: 1.1 $
37    * @author Michael Meyling
38    */
 
39    public class DefaultModuleAddress implements ModuleAddress {
40   
41    /** This class. */
42    private static final Class CLASS = DefaultModuleAddress.class;
43   
44    /** URL form of this address. */
45    private final URL url;
46   
47    /** Header (including protocol, host, port, user) but without file path. */
48    private final String header;
49   
50    /** Path (without protocol, host, port and file name). */
51    private final String path;
52   
53    /** File name of QEDEQ module including <code>.xml</code>. */
54    private final String fileName;
55   
56    /** Is module address relative? */
57    private final boolean relativeAddress;
58   
59    /** Is module address a file? */
60    private final boolean fileAddress;
61   
62    /** Module name. That is file name without <code>.xml</code> */
63    private final String name;
64   
65    /**
66    * Constructor.
67    *
68    * @param u Address of module. Must not be <code>null</code>.
69    * Must be a URL with protocol "file" or "http" and address a file
70    * with extension ".xml".
71    * @throws MalformedURLException Address is formally incorrect.
72    */
 
73  181 toggle public DefaultModuleAddress(final String u) throws MalformedURLException {
74   
75  181 this(u, (DefaultModuleAddress) null);
76    }
77   
78    /**
79    * Constructor.
80    *
81    * @param u Address of module. Must not be <code>null</code>.
82    * Must be a URL with protocol "file" or "http" and address a file
83    * with extension ".xml".
84    * @throws MalformedURLException Address is formally incorrect.
85    */
 
86  63 toggle public DefaultModuleAddress(final URL u) throws MalformedURLException {
87  63 this(u.toExternalForm(), (DefaultModuleAddress) null);
88    }
89   
90    /**
91    * Constructor.
92    *
93    * @param file File path of module. Must address a file
94    * with extension ".xml".
95    * @throws MalformedURLException Address is formally incorrect.
96    */
 
97  12 toggle public DefaultModuleAddress(final File file) throws MalformedURLException {
98  12 this(IoUtility.toUrl(file));
99    }
100   
101    /**
102    * Constructor.
103    *
104    * @param address Address of module. Must not be <code>null</code>.
105    * Must be a URL with protocol "file" or "http" (if <code>parent</code> is
106    * <code>null</code>) and address a file
107    * with extension ".xml".
108    * @param parent Address of parent module. Can be <code>null</code>.
109    * @throws MalformedURLException Address is formally incorrect.
110    */
 
111  480 toggle public DefaultModuleAddress(final String address, final ModuleAddress parent)
112    throws MalformedURLException {
113  480 final String method = "ModuleAddress(String, ModuleAddress)";
114  480 if (address == null) {
115  0 throw new NullPointerException();
116    }
117  480 URL urmel;
118  480 try {
119  480 if (parent != null) {
120  236 urmel = new URL(parent.getURL(), address);
121    } else {
122  244 urmel = new URL(address);
123    }
124    } catch (MalformedURLException e) {
125  6 Trace.trace(CLASS, this, method, "address=" + address);
126  6 Trace.trace(CLASS, this, method, "parent=" + parent);
127  6 Trace.trace(CLASS, this, method, e);
128  6 try {
129  6 final String newAddress = "file:" + address;
130  6 if (parent != null) {
131  0 urmel = new URL(parent.getURL(), newAddress);
132    } else {
133  6 urmel = new URL(newAddress);
134    }
135    } catch (MalformedURLException ex) {
136  0 throw e; // throw original exception
137    }
138    }
139  480 Trace.trace(CLASS, this, method, "protocol=" + urmel.getProtocol());
140  480 url = urmel;
141  480 fileAddress = url.getProtocol().equalsIgnoreCase("file");
142    /*
143    Trace.trace(this, METHOD, "url.getFile=" + this.url.getFile());
144    Trace.trace(this, METHOD, "url.getPath=" + this.url.getPath());
145    try {
146    Trace.trace(this, METHOD, "URI File=" +
147    new File(new URI(this.address)).getAbsoluteFile());
148    } catch (URISyntaxException e1) {
149    e1.printStackTrace();
150    }
151    */
152  480 final String p = urmel.getFile();
153  480 final int position = p.lastIndexOf("/");
154  480 if (position >= 0 && position + 1 < p.length()) {
155  480 this.path = p.substring(0, position) + "/";
156  480 this.fileName = p.substring(position + 1);
157    } else {
158  0 this.path = "";
159  0 this.fileName = p;
160    }
161  480 Trace.trace(CLASS, this, method, "path=" + this.path);
162  480 Trace.trace(CLASS, this, method, "fileName=" + this.fileName);
163  480 this.relativeAddress = !this.path.startsWith("/");
164  480 if (!this.fileName.endsWith(".xml")) {
165  0 throw new MalformedURLException("file name doesn't end with \".xml\": "
166    + this.fileName);
167    }
168  480 final int positionBefore = this.fileName.lastIndexOf(".");
169  480 final String mname = this.fileName.substring(0, positionBefore);
170  480 this.name = mname;
171  480 final int positionPath
172    = url.toString().lastIndexOf(this.path + this.fileName);
173  480 if (positionPath < 0) {
174  0 throw new IllegalArgumentException(
175    "couldn't determine begin of file path: "
176    + url.toString());
177    }
178  480 this.header = url.toString().substring(0, positionPath);
179    }
180   
181    /**
182    * Get module address as {@link ModuleContext}. Creates a new object.
183    *
184    * @return Module address as {@link ModuleContext}.
185    */
 
186  33080 toggle public final ModuleContext createModuleContext() {
187  33080 return new ModuleContext(this);
188    }
189   
190    /**
191    * Get address header (including protocol, host, port, user)
192    * but without file path.
193    *
194    * @return address header
195    */
 
196  0 toggle public final String getHeader() {
197  0 return header;
198    }
199   
200    /**
201    * Get address path (without protocol, host, port and file name).
202    *
203    * @return module path
204    */
 
205  0 toggle public final String getPath() {
206  0 return path;
207    }
208   
209    /**
210    * Get module file name.
211    *
212    * @return Module file name.
213    */
 
214  60 toggle public final String getFileName() {
215  60 return fileName;
216    }
217   
218    /**
219    * Get name of module (file name without <code>.xml</code>).
220    *
221    * @return Module name.
222    */
 
223  18 toggle public final String getName() {
224  18 return this.name;
225    }
226   
227    /**
228    * Get fully qualified URL of module.
229    *
230    * @return URL for QEDEQ module.
231    */
 
232  52101 toggle public final URL getURL() {
233  52101 return this.url;
234    }
235   
236    /**
237    * Was this module address created relatively?
238    *
239    * @return Relatively created?
240    */
 
241  0 toggle public final boolean isRelativeAddress() {
242  0 return this.relativeAddress;
243    }
244   
245    /**
246    * Is this a local QEDEQ file. That means the address starts with <code>file:</code>.
247    *
248    * @return Is the QEDEQ module a local file?
249    */
 
250  25230 toggle public final boolean isFileAddress() {
251  25230 return fileAddress;
252    }
253   
 
254  183 toggle public final String toString() {
255  183 return url.toString();
256    }
257   
 
258  1605 toggle public final int hashCode() {
259  1605 return url.hashCode();
260    }
261   
 
262  889 toggle public final boolean equals(final Object object) {
263  889 if (object == null || !(object instanceof DefaultModuleAddress)) {
264  0 return false;
265    }
266  889 return url.equals(((DefaultModuleAddress) object).url);
267    }
268   
269    /**
270    * Get the file name of the specified module.
271    *
272    * @param spec Here are the (perhaps relative) addresses to
273    * another module.
274    * @return File name of specified module.
275    */
 
276  196 toggle public static final String getModuleFileName(final Specification spec) {
277   
278  196 return spec.getName() + ".xml";
279    }
280   
 
281  196 toggle public final ModuleAddress[] getModulePaths(final Specification spec) throws IOException {
282   
283  196 final String fileNameEnd = getModuleFileName(spec);
284  196 final LocationList locations = spec.getLocationList();
285  196 final ModuleAddress[] result
286    = new ModuleAddress[locations.size()];
287  432 for (int i = 0; i < locations.size(); i++) {
288  236 String file = locations.get(i).getLocation();
289  236 if (file.equals(".")) {
290  196 file = "";
291  40 } else if (!file.endsWith("/")) {
292  40 file += "/";
293    }
294  236 file += fileNameEnd;
295  236 result[i] = new DefaultModuleAddress(file, this);
296    }
297  196 return result;
298    }
299   
300    /**
301    * Create relative address from <code>orgin</code> to <code>next</code>.
302    *
303    * @param origin This is the original location (URL!).
304    * @param next This should be the next location (URL!).
305    * @return Relative (or if necessary absolute) address.
306    */
 
307  0 toggle public static final String createRelativeAddress(final String origin,
308    final String next) {
309  0 if (origin.equals(next)) {
310  0 return "";
311    }
312  0 try {
313  0 final URL urlOrgin = new URL(origin);
314  0 final URL urlNext = new URL(next);
315   
316  0 if (urlOrgin.getProtocol().equals(urlNext.getProtocol())
317    && urlOrgin.getHost().equals(urlNext.getHost())
318    && urlOrgin.getPort() == urlNext.getPort()) {
319  0 final String org = urlOrgin.getFile();
320  0 final String nex = urlNext.getFile();
321  0 int i = -1; // position of next '/'
322  0 int j = 0; // position of last '/'
323  0 while (0 <= (i = org.indexOf("/", j))) {
324  0 if (i >= 0 && nex.length() > i
325    && org.substring(j, i).equals(
326    nex.substring(j, i))) {
327  0 j = i + 1;
328    } else {
329  0 break;
330    }
331    }
332  0 if (j > 0) {
333  0 i = j;
334  0 StringBuffer result = new StringBuffer(nex.length());
335  0 while (0 <= (i = org.indexOf("/", i))) {
336  0 i++;
337  0 result.append("../");
338    }
339  0 result.append(nex.substring(j));
340  0 return result.toString();
341    } else {
342  0 return "/" + nex;
343    }
344    } else { // no relative address possible
345  0 return urlNext.toString();
346    }
347    } catch (MalformedURLException e) {
348  0 return next;
349    }
350   
351    }
352   
353    /**
354    * Get module address with new ending. E.g.: ".html" instead of ".qedeq".
355    *
356    * @param address The address of something (e.g.: a module).
357    * @param newEnding This should be the new ending (e.g.: "html").
358    * @return module address with substituted ending
359    */
 
360  0 toggle public static final String newEnding(final String address,
361    final String newEnding) {
362  0 if (address.length() == 0) {
363  0 return "";
364    }
365  0 final int i = address.lastIndexOf(".");
366  0 if (i > 0) {
367  0 return address.substring(0, i + 1) + newEnding;
368    } else {
369  0 return address + "." + newEnding;
370    }
371    }
372   
373    }
374