001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.oauth2.sdk.id;
019
020
021import com.nimbusds.oauth2.sdk.util.StringUtils;
022import net.jcip.annotations.Immutable;
023
024import java.net.URI;
025import java.net.URISyntaxException;
026
027
028/**
029 * Issuer identifier.
030 *
031 * <p>Valid issuer identifiers are URIs with "https" schema and no query or
032 * fragment component.
033 */
034@Immutable
035public final class Issuer extends Identifier {
036        
037        
038        private static final long serialVersionUID = -8033463330193076151L;
039        
040        
041        /**
042         * Checks if the specified string represents a valid issuer identifier.
043         * This method is {@code null}-safe.
044         *
045         * @param value The issuer string.
046         *
047         * @return {@code true} if the string represents a valid issuer
048         *         identifier, else {@code false}.
049         */
050        public static boolean isValid(final String value) {
051
052                if (value == null)
053                        return false;
054
055                try {
056                        return isValid(new URI(value));
057
058                } catch (URISyntaxException e) {
059
060                        return false;
061                }
062        }
063
064
065        /**
066         * Checks if the specified issuer is a valid identifier. This method is
067         * {@code null}-safe.
068         *
069         * @param value The issuer.
070         *
071         * @return {@code true} if the value is a valid identifier, else
072         *         {@code false}.
073         */
074        public static boolean isValid(final Issuer value) {
075
076                if (value == null)
077                        return false;
078
079                try {
080                        return isValid(new URI(value.getValue()));
081
082                } catch (URISyntaxException e) {
083
084                        return false;
085                }
086        }
087
088
089        /**
090         * Checks if the specified URI represents a valid issuer identifier.
091         * This method is {@code null}-safe.
092         *
093         * @param value The URI.
094         *
095         * @return {@code true} if the values represents a valid issuer
096         *         identifier, else {@code false}.
097         */
098        public static boolean isValid(final URI value) {
099
100                if (value == null)
101                        return false;
102
103                if (value.getScheme() == null || ! value.getScheme().equalsIgnoreCase("https"))
104                        return false;
105
106                if (value.getRawQuery() != null)
107                        return false;
108
109                return value.getRawFragment() == null;
110
111        }
112
113
114        /**
115         * Creates a new issuer identifier with the specified value.
116         *
117         * @param value The issuer identifier value. Must not be {@code null}
118         *              or empty string.
119         */
120        public Issuer(final String value) {
121
122                super(value);
123        }
124
125
126        /**
127         * Creates a new issuer identifier with the specified URI value.
128         *
129         * @param value The URI value. Must not be {@code null}.
130         */
131        public Issuer(final URI value) {
132
133                super(value.toString());
134        }
135
136
137        /**
138         * Creates a new issuer identifier with the specified value.
139         *
140         * @param value The value. Must not be {@code null}.
141         */
142        public Issuer(final Identifier value) {
143
144                super(value.getValue());
145        }
146
147
148        /**
149         * Checks if this issuer is a valid identifier. This method is
150         * {@code null}-safe.
151         *
152         * @return {@code true} if the value is a valid identifier, else
153         *         {@code false}.
154         */
155        public boolean isValid() {
156
157                return Issuer.isValid(this);
158        }
159
160
161        @Override
162        public boolean equals(final Object object) {
163        
164                return object instanceof Issuer && this.toString().equals(object.toString());
165        }
166
167
168        /**
169         * Compares this issuer's URI to another issuer's URI, ignoring any
170         * trailing slashes. If either issuer is {@link #isValid() invalid} this
171         * method falls back to the regular {@link #equals(Object)} method.
172         *
173         * @param other The other issuer, if {@code null} this method returns
174         *              {@code false}.
175         *
176         * @return {@code true} if the URIs are equal, ignoring any trailing
177         *         slashes, else {@code false}.
178         */
179        public boolean equalsIgnoreTrailingSlash(final Issuer other) {
180
181                if (other == null) {
182                        return false;
183                }
184
185                if (! isValid() || ! other.isValid()) {
186                        // Issuer not URI or otherwise invalid, fall back to
187                        // regular equals method
188                        return equals(other);
189                }
190
191                // Strip trailing slash for equality check
192                final URI thisURI = URI.create(this.toString().replaceFirst("/*$", ""));
193                final URI otherURI = URI.create(other.toString().replaceFirst("/*$", ""));
194
195                return thisURI.equals(otherURI);
196        }
197        
198        
199        /**
200         * Parses an issuer from the specified string.
201         *
202         * @param s The string to parse, {@code null} or empty if no issuer is
203         *          specified.
204         *
205         * @return The issuer, {@code null} if the parsed string was
206         *         {@code null} or empty.
207         */
208        public static Issuer parse(final String s) {
209                
210                if (StringUtils.isBlank(s))
211                        return null;
212                
213                return new Issuer(s);
214        }
215}