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