001    /**
002     * Copyright (c) 2000-present 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.kernel.util;
016    
017    import com.liferay.portal.kernel.concurrent.ConcurrentReferenceValueHashMap;
018    import com.liferay.portal.kernel.memory.FinalizeManager;
019    
020    import java.util.Map;
021    import java.util.regex.Matcher;
022    import java.util.regex.Pattern;
023    
024    /**
025     * @author Connor McKay
026     * @author Brian Wing Shun Chan
027     */
028    public class StringParserFragment {
029    
030            public static StringParserFragment create(String chunk) {
031                    StringParserFragment stringParserFragment = _stringParserFragments.get(
032                            chunk);
033    
034                    if (stringParserFragment == null) {
035                            stringParserFragment = new StringParserFragment(chunk);
036    
037                            _stringParserFragments.put(chunk, stringParserFragment);
038                    }
039    
040                    return stringParserFragment;
041            }
042    
043            public String getName() {
044                    return _name;
045            }
046    
047            public String getPattern() {
048                    return _pattern.toString();
049            }
050    
051            public String getToken() {
052                    return _token;
053            }
054    
055            public boolean isRaw() {
056                    return _raw;
057            }
058    
059            public boolean matches(String parameter) {
060                    Matcher matcher = _pattern.matcher(parameter);
061    
062                    return matcher.matches();
063            }
064    
065            protected StringParserFragment(String chunk) {
066                    chunk = chunk.substring(1, chunk.length() - 1);
067    
068                    if (Validator.isNull(chunk)) {
069                            throw new IllegalArgumentException("Fragment is null");
070                    }
071    
072                    String[] chunkParts = chunk.split(StringPool.COLON, 2);
073    
074                    String name = null;
075    
076                    if (chunkParts.length == 2) {
077                            name = chunkParts[0];
078                            String pattern = chunkParts[1];
079    
080                            if (Validator.isNull(pattern)) {
081                                    throw new IllegalArgumentException("Pattern is null");
082                            }
083    
084                            _pattern = Pattern.compile(pattern);
085                    }
086                    else {
087                            name = chunkParts[0];
088                            _pattern = _defaultPattern;
089                    }
090    
091                    if (Validator.isNull(name)) {
092                            throw new IllegalArgumentException("Name is null");
093                    }
094    
095                    if (name.startsWith(StringPool.PERCENT)) {
096                            name = name.substring(1);
097    
098                            if (Validator.isNull(name)) {
099                                    throw new IllegalArgumentException("Name is null");
100                            }
101    
102                            _raw = true;
103                    }
104                    else {
105                            _raw = false;
106                    }
107    
108                    _name = name;
109    
110                    _token = StringPool.OPEN_CURLY_BRACE.concat(_name).concat(
111                            StringPool.CLOSE_CURLY_BRACE);
112            }
113    
114            private static final Pattern _defaultPattern = Pattern.compile("[^/\\.]+");
115            private static final Map<String, StringParserFragment>
116                    _stringParserFragments = new ConcurrentReferenceValueHashMap<>(
117                            FinalizeManager.SOFT_REFERENCE_FACTORY);
118    
119            private final String _name;
120            private final Pattern _pattern;
121            private final boolean _raw;
122            private final String _token;
123    
124    }