001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.tools;
016    
017    import java.util.Map;
018    import java.util.Set;
019    import java.util.TreeMap;
020    import java.util.TreeSet;
021    
022    /**
023     * A dummy container for friendly URL route data used by source formatter.
024     * Implements the comparable interface to sort routes by increasing generality.
025     *
026     * @author Connor McKay
027     */
028    public class ComparableRoute implements Comparable<ComparableRoute> {
029    
030            public static boolean hasRegex(String fragment) {
031                    if (fragment.indexOf(":") != -1) {
032                            return true;
033                    }
034                    else {
035                            return false;
036                    }
037            }
038    
039            public static boolean isCaptureFragment(String fragment) {
040                    if (fragment.indexOf("{") != -1) {
041                            return true;
042                    }
043                    else {
044                            return false;
045                    }
046            }
047    
048            public static boolean isMatchAny(String fragment) {
049                    return fragment.matches(".*\\{.+?:\\.\\*\\}.*");
050            }
051    
052            public ComparableRoute(String pattern) {
053                    _pattern = pattern;
054            }
055    
056            public void addGeneratedParameter(String name, String pattern) {
057                    _generatedParameters.put(name, pattern);
058            }
059    
060            public void addIgnoredParameter(String name) {
061                    _ignoredParameters.add(name);
062            }
063    
064            public void addImplicitParameter(String name, String value) {
065                    _implicitParameters.put(name, value);
066            }
067    
068            public void addOverriddenParameter(String name, String value) {
069                    _overriddenParameters.put(name, value);
070            }
071    
072            public int compareTo(ComparableRoute comparableRoute) {
073    
074                    // Don't split on .*
075    
076                    String[] _fragments = _pattern.split("[/\\.](?!\\*)");
077    
078                    String pattern = comparableRoute.getPattern();
079    
080                    String[] fragments = pattern.split("[/\\.](?!\\*)");
081    
082                    int i;
083    
084                    for (i = 0; (i < _fragments.length) && (i < fragments.length); i++) {
085                            String _fragment = _fragments[i];
086                            String fragment = fragments[i];
087    
088                            // Capture fragments are more general than static ones
089    
090                            if (!isCaptureFragment(_fragment) && isCaptureFragment(fragment)) {
091                                    return -1;
092                            }
093    
094                            if (isCaptureFragment(_fragment) && !isCaptureFragment(fragment)) {
095                                    return 1;
096                            }
097    
098                            // A fragment matching .* is more general than anything
099    
100                            if (!isMatchAny(_fragment) && isMatchAny(fragment)) {
101                                    return -1;
102                            }
103    
104                            if (isMatchAny(_fragment) && !isMatchAny(fragment)) {
105                                    return 1;
106                            }
107    
108                            // Not having a regex is more general than having a custom one
109    
110                            if (hasRegex(_fragment) && !hasRegex(fragment)) {
111                                    return -1;
112                            }
113    
114                            if (!hasRegex(_fragment) && hasRegex(fragment)) {
115                                    return 1;
116                            }
117                    }
118    
119                    // Having more fragments is more general
120    
121                    if ((i < fragments.length) && (i >= _fragments.length)) {
122                            return -1;
123                    }
124    
125                    if ((i < _fragments.length) && (i >= fragments.length)) {
126                            return 1;
127                    }
128    
129                    // Having fewer implicit parameters is more general
130    
131                    Map<String, String> implicitParameters =
132                            comparableRoute.getImplicitParameters(); 
133    
134                    if (_implicitParameters.size() > implicitParameters.size()) {
135                            return -1;
136                    }
137    
138                    if (_implicitParameters.size() < implicitParameters.size()) {
139                            return 1;
140                    }
141    
142                    return _pattern.compareTo(comparableRoute.getPattern());
143            }
144    
145            public boolean equals(Object obj) {
146                    if (this == obj) {
147                            return true;
148                    }
149    
150                    if (!(obj instanceof ComparableRoute)) {
151                            return false;
152                    }
153    
154                    ComparableRoute comparableRoute = (ComparableRoute)obj;
155    
156                    if (compareTo(comparableRoute) == 0) {
157                            return true;
158                    }
159                    else {
160                            return false;
161                    }
162            }
163    
164            public Map<String, String> getGeneratedParameters() {
165                    return _generatedParameters;
166            }
167    
168            public Set<String> getIgnoredParameters() {
169                    return _ignoredParameters;
170            }
171    
172            public Map<String, String> getImplicitParameters() {
173                    return _implicitParameters;
174            }
175    
176            public Map<String, String> getOverriddenParameters() {
177                    return _overriddenParameters;
178            }
179    
180            public String getPattern() {
181                    return _pattern;
182            }
183    
184            private Map<String, String> _generatedParameters =
185                    new TreeMap<String, String>();
186            private Set<String> _ignoredParameters = new TreeSet<String>();
187            private Map<String, String> _implicitParameters =
188                    new TreeMap<String, String>();
189            private Map<String, String> _overriddenParameters =
190                    new TreeMap<String, String>();
191            private String _pattern;
192    
193    }