EMMA Coverage Report (generated Fri Feb 14 08:28:31 UTC 2014)
[all classes][org.qedeq.kernel.se.common]

COVERAGE SUMMARY FOR SOURCE FILE [DefaultModuleAddress.java]

nameclass, %method, %block, %line, %
DefaultModuleAddress.java100% (1/1)100% (22/22)93%  (515/551)94%  (103.9/111)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class DefaultModuleAddress100% (1/1)100% (22/22)93%  (515/551)94%  (103.9/111)
DefaultModuleAddress (String, ModuleAddress): void 100% (1/1)89%  (244/275)91%  (40/44)
<static initializer> 100% (1/1)93%  (13/14)96%  (1.9/2)
createRelativeAddress (String, String): String 100% (1/1)95%  (52/55)86%  (12/14)
getModulePaths (Specification): ModuleAddress [] 100% (1/1)99%  (73/74)93%  (13/14)
DefaultModuleAddress (): void 100% (1/1)100% (5/5)100% (2/2)
DefaultModuleAddress (File): void 100% (1/1)100% (6/6)100% (2/2)
DefaultModuleAddress (String): void 100% (1/1)100% (6/6)100% (2/2)
DefaultModuleAddress (URL): void 100% (1/1)100% (7/7)100% (2/2)
DefaultModuleAddress (boolean, String): void 100% (1/1)100% (44/44)100% (13/13)
createModuleContext (): ModuleContext 100% (1/1)100% (5/5)100% (1/1)
createRelative (String, String): String 100% (1/1)100% (10/10)100% (2/2)
equals (Object): boolean 100% (1/1)100% (12/12)100% (3/3)
getFileName (): String 100% (1/1)100% (3/3)100% (1/1)
getHeader (): String 100% (1/1)100% (3/3)100% (1/1)
getModuleFileName (Specification): String 100% (1/1)100% (10/10)100% (1/1)
getName (): String 100% (1/1)100% (3/3)100% (1/1)
getPath (): String 100% (1/1)100% (3/3)100% (1/1)
getUrl (): String 100% (1/1)100% (3/3)100% (1/1)
hashCode (): int 100% (1/1)100% (4/4)100% (1/1)
isFileAddress (): boolean 100% (1/1)100% (3/3)100% (1/1)
isRelativeAddress (): boolean 100% (1/1)100% (3/3)100% (1/1)
toString (): String 100% (1/1)100% (3/3)100% (1/1)

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

[all classes][org.qedeq.kernel.se.common]
EMMA 2.1.5320 (stable) (C) Vladimir Roubtsov