001
014
015 package com.liferay.portal.template;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.template.TemplateException;
020 import com.liferay.portal.kernel.template.TemplateResource;
021 import com.liferay.portal.kernel.template.URLTemplateResource;
022 import com.liferay.portal.kernel.util.CharPool;
023 import com.liferay.portal.kernel.util.FileUtil;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.StringUtil;
026 import com.liferay.portal.kernel.util.Validator;
027
028 import java.io.IOException;
029
030 import java.net.URL;
031
032 import java.util.ArrayList;
033 import java.util.List;
034
035
038 public abstract class URLResourceParser implements TemplateResourceParser {
039
040 @Override
041 public TemplateResource getTemplateResource(String templateId)
042 throws TemplateException {
043
044 templateId = normalizePath(templateId);
045
046 try {
047 URL url = getURL(templateId);
048
049 if (url == null) {
050 return null;
051 }
052
053 return new URLTemplateResource(templateId, url);
054 }
055 catch (IOException ioe) {
056 throw new TemplateException(ioe);
057 }
058 }
059
060 public abstract URL getURL(String templateId) throws IOException;
061
062 @Override
063 public boolean isTemplateResourceValid(String templateId, String langType) {
064 if (Validator.isBlank(templateId)) {
065 return true;
066 }
067
068 char[] chars = templateId.toCharArray();
069
070 for (int i = 0; i < chars.length; i++) {
071 char c = chars[i];
072
073 if ((c == CharPool.PERCENT) || (c == CharPool.POUND) ||
074 (c == CharPool.QUESTION) || (c == CharPool.SEMICOLON)) {
075
076 if (_log.isWarnEnabled()) {
077 _log.warn(
078 "Unable to load template " + templateId +
079 " because the template name contains one or more " +
080 "special characters: %, #, ?, or ;");
081 }
082
083 return false;
084 }
085
086 if (c == CharPool.BACK_SLASH) {
087 if (_log.isWarnEnabled()) {
088 _log.warn(
089 "Unable to load template " + templateId +
090 " because the template name contains a backslash");
091 }
092
093 return false;
094 }
095 }
096
097 String extension = FileUtil.getExtension(templateId);
098
099 if (!extension.equals(langType)) {
100 return false;
101 }
102
103 return true;
104 }
105
106 protected static String normalizePath(String path) {
107 List<String> elements = new ArrayList<>();
108
109 boolean absolutePath = false;
110
111 int previousIndex = -1;
112
113 for (int index;
114 (index = path.indexOf(CharPool.SLASH, previousIndex + 1)) != -1;
115 previousIndex = index) {
116
117 if ((previousIndex + 1) == index) {
118
119
120
121 if (previousIndex == -1) {
122 absolutePath = true;
123
124 continue;
125 }
126
127
128
129 throw new IllegalArgumentException(
130 "Unable to parse path " + path);
131 }
132
133 String pathElement = path.substring(previousIndex + 1, index);
134
135
136
137 if (pathElement.equals(StringPool.PERIOD)) {
138 continue;
139 }
140
141
142
143 if (pathElement.equals(StringPool.DOUBLE_PERIOD)) {
144 if (elements.isEmpty()) {
145 throw new IllegalArgumentException(
146 "Unable to parse path " + path);
147 }
148
149 elements.remove(elements.size() - 1);
150
151 continue;
152 }
153
154
155
156 elements.add(pathElement);
157 }
158
159 if (previousIndex == -1) {
160 elements.add(path);
161 }
162 else if ((previousIndex + 1) < path.length()) {
163 elements.add(path.substring(previousIndex + 1));
164 }
165
166 String normalizedPath = StringUtil.merge(elements, StringPool.SLASH);
167
168 if (absolutePath) {
169 normalizedPath = StringPool.SLASH.concat(normalizedPath);
170 }
171
172 return normalizedPath;
173 }
174
175 private static final Log _log = LogFactoryUtil.getLog(
176 URLResourceParser.class);
177
178 }