001package org.xbib.standardnumber;
002
003import java.net.URI;
004import java.util.regex.Matcher;
005import java.util.regex.Pattern;
006
007/**
008 * ARK Archival Resource Key
009 *
010 * An ARK is a Uniform Resource Locator (URL) that is a multi-purpose identifier
011 * for information objects of any type. An ARK contains the label ark: after the
012 * hostname, an URL request terminated by '?' returns a brief metadata record,
013 * and an URL request terminated by '??' returns metadata that includes a commitment
014 * statement from the current service provider.
015 *
016 * The ARK and its inflections ('?' and '??') gain access to three facets of a
017 * provider's ability to provide persistence.
018 *
019 * Implicit in the design of the ARK scheme is that persistence is purely a matter
020 * of service and not a property of a naming syntax.
021 *
022 * @see <a href="http://tools.ietf.org/html/draft-kunze-ark-18">ARK IETF RFC</a>
023 * 
024 * @see <a href="http://www.cdlib.org/services/uc3/docs/jak_ARKs_Berlin_2012.pdf">10 years ARK</a>
025 */
026public class ARK extends AbstractStandardNumber implements Comparable<ARK> {
027
028    private static final Pattern PATTERN = Pattern.compile("[\\p{Graph}\\p{Punct}]{0,48}");
029
030    private static final Pattern URI_PATTERN = Pattern.compile("^(ark)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
031
032    private URI value;
033
034    @Override
035    public String type() {
036        return "ark";
037    }
038
039    @Override
040    public int compareTo(ARK ark) {
041        return ark != null ? normalizedValue().compareTo(ark.normalizedValue()) : -1;
042    }
043
044    @Override
045    public ARK set(CharSequence value) {
046        try {
047            this.value = value != null ? URI.create(value.toString()) : null;
048        } catch (IllegalArgumentException e) {
049            this.value = null;
050
051        }
052        return this;
053    }
054
055    @Override
056    public ARK createChecksum(boolean checksum) {
057        return this;
058    }
059
060    @Override
061    public ARK normalize() {
062        if (value == null) {
063            return this;
064        }
065        String s = value.toString();
066        Matcher m = URI_PATTERN.matcher(s);
067        if (m.find()) {
068            this.value = URI.create(s.substring(m.start(), m.end()));
069        }
070        m = PATTERN.matcher(s);
071        if (m.find()) {
072            this.value = URI.create(s.substring(m.start(), m.end()));
073        }
074        return this;
075    }
076
077    @Override
078    public boolean isValid() {
079       return "ark".equals(value.getScheme());
080    }
081
082    /**
083     * No verification.
084     *
085     * @return this ARK
086     * @throws NumberFormatException
087     */
088    @Override
089    public ARK verify() throws NumberFormatException {
090        if (value == null || !"ark".equals(value.getScheme())) {
091            throw new NumberFormatException();
092        }
093        return this;
094    }
095
096    @Override
097    public String normalizedValue() {
098        return value != null ? value.toString() : null;
099    }
100
101    @Override
102    public String format() {
103        return value != null ? value.toString() : null;
104    }
105
106    public URI asURI() {
107        return value;
108    }
109
110    public ARK reset() {
111        this.value = null;
112        return this;
113    }
114}