001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
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                    return fragment.contains(":");
032            }
033    
034            public static boolean isCaptureFragment(String fragment) {
035                    return fragment.contains("{");
036            }
037    
038            public static boolean isMatchAny(String fragment) {
039                    return fragment.matches(".*\\{.+?:\\.\\*\\}.*");
040            }
041    
042            public ComparableRoute(String pattern) {
043                    _pattern = pattern;
044            }
045    
046            public void addGeneratedParameter(String name, String pattern) {
047                    _generatedParameters.put(name, pattern);
048            }
049    
050            public void addIgnoredParameter(String name) {
051                    _ignoredParameters.add(name);
052            }
053    
054            public void addImplicitParameter(String name, String value) {
055                    _implicitParameters.put(name, value);
056            }
057    
058            public void addOverriddenParameter(String name, String value) {
059                    _overriddenParameters.put(name, value);
060            }
061    
062            public int compareTo(ComparableRoute comparableRoute) {
063    
064                    // Don't split on .*
065    
066                    String[] _fragments = _pattern.split("[/\\.](?!\\*)");
067    
068                    String pattern = comparableRoute.getPattern();
069    
070                    String[] fragments = pattern.split("[/\\.](?!\\*)");
071    
072                    int i;
073    
074                    for (i = 0; (i < _fragments.length) && (i < fragments.length); i++) {
075                            String _fragment = _fragments[i];
076                            String fragment = fragments[i];
077    
078                            // Capture fragments are more general than static ones
079    
080                            if (!isCaptureFragment(_fragment) && isCaptureFragment(fragment)) {
081                                    return -1;
082                            }
083    
084                            if (isCaptureFragment(_fragment) && !isCaptureFragment(fragment)) {
085                                    return 1;
086                            }
087    
088                            // A fragment matching .* is more general than anything
089    
090                            if (!isMatchAny(_fragment) && isMatchAny(fragment)) {
091                                    return -1;
092                            }
093    
094                            if (isMatchAny(_fragment) && !isMatchAny(fragment)) {
095                                    return 1;
096                            }
097    
098                            // Not having a regex is more general than having a custom one
099    
100                            if (hasRegex(_fragment) && !hasRegex(fragment)) {
101                                    return -1;
102                            }
103    
104                            if (!hasRegex(_fragment) && hasRegex(fragment)) {
105                                    return 1;
106                            }
107                    }
108    
109                    // Having more fragments is more general
110    
111                    if ((i < fragments.length) && (i >= _fragments.length)) {
112                            return -1;
113                    }
114    
115                    if ((i < _fragments.length) && (i >= fragments.length)) {
116                            return 1;
117                    }
118    
119                    // Having fewer implicit parameters is more general
120    
121                    Map<String, String> implicitParameters =
122                            comparableRoute.getImplicitParameters();
123    
124                    if (_implicitParameters.size() > implicitParameters.size()) {
125                            return -1;
126                    }
127    
128                    if (_implicitParameters.size() < implicitParameters.size()) {
129                            return 1;
130                    }
131    
132                    return _pattern.compareTo(comparableRoute.getPattern());
133            }
134    
135            @Override
136            public boolean equals(Object obj) {
137                    if (this == obj) {
138                            return true;
139                    }
140    
141                    if (!(obj instanceof ComparableRoute)) {
142                            return false;
143                    }
144    
145                    ComparableRoute comparableRoute = (ComparableRoute)obj;
146    
147                    if (compareTo(comparableRoute) == 0) {
148                            return true;
149                    }
150                    else {
151                            return false;
152                    }
153            }
154    
155            public Map<String, String> getGeneratedParameters() {
156                    return _generatedParameters;
157            }
158    
159            public Set<String> getIgnoredParameters() {
160                    return _ignoredParameters;
161            }
162    
163            public Map<String, String> getImplicitParameters() {
164                    return _implicitParameters;
165            }
166    
167            public Map<String, String> getOverriddenParameters() {
168                    return _overriddenParameters;
169            }
170    
171            public String getPattern() {
172                    return _pattern;
173            }
174    
175            private Map<String, String> _generatedParameters =
176                    new TreeMap<String, String>();
177            private Set<String> _ignoredParameters = new TreeSet<String>();
178            private Map<String, String> _implicitParameters =
179                    new TreeMap<String, String>();
180            private Map<String, String> _overriddenParameters =
181                    new TreeMap<String, String>();
182            private String _pattern;
183    
184    }