1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
|
23 | |
|
24 | |
|
25 | |
|
26 | |
|
27 | |
|
28 | |
|
29 | |
|
30 | |
|
31 | |
|
32 | |
|
33 | |
package net.sourceforge.pebble.permalink; |
34 | |
|
35 | |
import net.sourceforge.pebble.api.permalink.PermalinkProvider; |
36 | |
import net.sourceforge.pebble.domain.*; |
37 | |
|
38 | |
import java.text.SimpleDateFormat; |
39 | |
import java.util.HashMap; |
40 | |
import java.util.Iterator; |
41 | |
import java.util.List; |
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | |
|
54 | |
|
55 | |
|
56 | 52 | public class Latin1SeoPermalinkProvider implements PermalinkProvider { |
57 | |
|
58 | |
|
59 | |
|
60 | |
|
61 | |
private static final String DAY_PERMALINK_REGEX = "/\\d\\d\\d\\d/\\d\\d/\\d\\d"; |
62 | |
|
63 | |
|
64 | |
|
65 | |
|
66 | |
private static final String MONTH_PERMALINK_REGEX = "/\\d\\d\\d\\d/\\d\\d"; |
67 | |
|
68 | |
|
69 | |
|
70 | |
|
71 | |
private static final String BLOG_ENTRY_PERMALINK_REGEX = "/[\\w-]*"; |
72 | |
|
73 | |
|
74 | |
|
75 | |
|
76 | |
private Blog blog; |
77 | |
|
78 | |
|
79 | |
|
80 | |
|
81 | |
|
82 | |
|
83 | |
public Blog getBlog() { |
84 | 252 | return this.blog; |
85 | |
} |
86 | |
|
87 | |
|
88 | |
|
89 | |
|
90 | |
|
91 | |
|
92 | |
public void setBlog(Blog blog) { |
93 | 52 | this.blog = blog; |
94 | 52 | } |
95 | |
|
96 | |
|
97 | |
|
98 | |
|
99 | |
|
100 | |
|
101 | |
public synchronized String getPermalink(BlogEntry blogEntry) { |
102 | 188 | if (blogEntry.getTitle() == null || blogEntry.getTitle().length() == 0) { |
103 | 8 | return buildPermalink(blogEntry); |
104 | |
} else { |
105 | 180 | BlogService service = new BlogService(); |
106 | 180 | List<BlogEntry> entries = getBlog().getBlogEntries(); |
107 | 180 | int count = 0; |
108 | 300 | for (int i = entries.size() - 1; i >= 0 && !entries.get(i).getId().equals(blogEntry.getId()); i--) { |
109 | 120 | if (entries.get(i).getTitle().equals(blogEntry.getTitle())) { |
110 | 16 | count++; |
111 | |
} |
112 | |
} |
113 | |
|
114 | 180 | if (count == 0) { |
115 | 168 | return buildPermalink(blogEntry); |
116 | |
} else { |
117 | 12 | return buildPermalink(blogEntry) + "_" + blogEntry.getId(); |
118 | |
} |
119 | |
} |
120 | |
} |
121 | |
|
122 | |
private String buildPermalink(BlogEntry blogEntry) { |
123 | 188 | String title = blogEntry.getTitle(); |
124 | 188 | if (title == null || title.length() == 0) { |
125 | 8 | title = "" + blogEntry.getId(); |
126 | |
} else { |
127 | 180 | title = title.toLowerCase(); |
128 | 180 | title = title.replaceAll("[\\. ,;/\\\\_]", "-"); |
129 | 180 | for (String search : characterSubstitutions.keySet()) { |
130 | 11700 | title = title.replaceAll(search, characterSubstitutions.get(search)); |
131 | |
} |
132 | 180 | title = title.replaceAll("[^a-z0-9-]", ""); |
133 | 180 | title = title.replaceAll("-+", "-"); |
134 | 180 | title = title.replaceAll("^-*", ""); |
135 | 180 | title = title.replaceAll("-*$", ""); |
136 | |
} |
137 | |
|
138 | |
|
139 | 188 | if (title == null || title.length() == 0) { |
140 | 24 | title = "" + blogEntry.getId(); |
141 | |
} |
142 | |
|
143 | 188 | return "/" + title; |
144 | |
} |
145 | |
|
146 | |
|
147 | |
public boolean isBlogEntryPermalink(String uri) { |
148 | 16 | if (uri != null) { |
149 | 12 | return uri.matches(BLOG_ENTRY_PERMALINK_REGEX); |
150 | |
} else { |
151 | 4 | return false; |
152 | |
} |
153 | |
} |
154 | |
|
155 | |
public BlogEntry getBlogEntry(String uri) { |
156 | 20 | BlogService service = new BlogService(); |
157 | 20 | Iterator it = getBlog().getBlogEntries().iterator(); |
158 | 44 | while (it.hasNext()) { |
159 | |
try { |
160 | 44 | BlogEntry blogEntry = service.getBlogEntry(getBlog(), "" + ((BlogEntry) it.next()).getId()); |
161 | |
|
162 | |
|
163 | 44 | if (blogEntry.getLocalPermalink().endsWith(uri)) { |
164 | 20 | return blogEntry; |
165 | |
} |
166 | 0 | } catch (BlogServiceException e) { |
167 | |
|
168 | 24 | } |
169 | |
} |
170 | |
|
171 | 0 | return null; |
172 | |
} |
173 | |
|
174 | |
|
175 | |
|
176 | |
|
177 | |
|
178 | |
|
179 | |
|
180 | |
public String getPermalink(Month month) { |
181 | 4 | SimpleDateFormat format = new SimpleDateFormat("'/'yyyy'/'MM"); |
182 | 4 | format.setTimeZone(blog.getTimeZone()); |
183 | 4 | return format.format(month.getDate()); |
184 | |
} |
185 | |
|
186 | |
|
187 | |
|
188 | |
|
189 | |
|
190 | |
|
191 | |
|
192 | |
|
193 | |
public boolean isMonthPermalink(String uri) { |
194 | 20 | if (uri != null) { |
195 | 16 | return uri.matches(MONTH_PERMALINK_REGEX); |
196 | |
} else { |
197 | 4 | return false; |
198 | |
} |
199 | |
} |
200 | |
|
201 | |
|
202 | |
|
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | |
public Month getMonth(String uri) { |
208 | 4 | String year = uri.substring(1, 5); |
209 | 4 | String month = uri.substring(6, 8); |
210 | |
|
211 | 4 | return getBlog().getBlogForMonth(Integer.parseInt(year), Integer.parseInt(month)); |
212 | |
} |
213 | |
|
214 | |
|
215 | |
|
216 | |
|
217 | |
|
218 | |
|
219 | |
|
220 | |
public String getPermalink(Day day) { |
221 | 4 | SimpleDateFormat format = new SimpleDateFormat("'/'yyyy'/'MM'/'dd"); |
222 | 4 | format.setTimeZone(blog.getTimeZone()); |
223 | 4 | return format.format(day.getDate()); |
224 | |
} |
225 | |
|
226 | |
|
227 | |
|
228 | |
|
229 | |
|
230 | |
|
231 | |
|
232 | |
|
233 | |
public boolean isDayPermalink(String uri) { |
234 | 20 | if (uri != null) { |
235 | 16 | return uri.matches(DAY_PERMALINK_REGEX); |
236 | |
} else { |
237 | 4 | return false; |
238 | |
} |
239 | |
} |
240 | |
|
241 | |
|
242 | |
|
243 | |
|
244 | |
|
245 | |
|
246 | |
|
247 | |
public Day getDay(String uri) { |
248 | 4 | String year = uri.substring(1, 5); |
249 | 4 | String month = uri.substring(6, 8); |
250 | 4 | String day = uri.substring(9, 11); |
251 | |
|
252 | 4 | return getBlog().getBlogForDay(Integer.parseInt(year), |
253 | |
Integer.parseInt(month), Integer.parseInt(day)); |
254 | |
} |
255 | |
|
256 | |
|
257 | |
|
258 | |
|
259 | |
|
260 | |
private static final HashMap<String, String> characterSubstitutions; |
261 | |
|
262 | |
static { |
263 | |
|
264 | 4 | characterSubstitutions = new HashMap<String, String>(); |
265 | |
|
266 | 4 | characterSubstitutions.put("\u00B2", "2"); |
267 | 4 | characterSubstitutions.put("\u00B3", "3"); |
268 | |
|
269 | 4 | characterSubstitutions.put("\u00C0", "A"); |
270 | 4 | characterSubstitutions.put("\u00C1", "A"); |
271 | 4 | characterSubstitutions.put("\u00C2", "A"); |
272 | 4 | characterSubstitutions.put("\u00C3", "A"); |
273 | 4 | characterSubstitutions.put("\u00C4", "A"); |
274 | 4 | characterSubstitutions.put("\u00C5", "A"); |
275 | 4 | characterSubstitutions.put("\u00C6", "AE"); |
276 | 4 | characterSubstitutions.put("\u00C7", "C"); |
277 | 4 | characterSubstitutions.put("\u00C8", "E"); |
278 | 4 | characterSubstitutions.put("\u00C9", "E"); |
279 | 4 | characterSubstitutions.put("\u00CA", "E"); |
280 | 4 | characterSubstitutions.put("\u00CB", "E"); |
281 | 4 | characterSubstitutions.put("\u00CC", "I"); |
282 | 4 | characterSubstitutions.put("\u00CD", "I"); |
283 | 4 | characterSubstitutions.put("\u00CE", "I"); |
284 | 4 | characterSubstitutions.put("\u00CF", "I"); |
285 | |
|
286 | 4 | characterSubstitutions.put("\u00D0", "D"); |
287 | 4 | characterSubstitutions.put("\u00D1", "N"); |
288 | 4 | characterSubstitutions.put("\u00D2", "O"); |
289 | 4 | characterSubstitutions.put("\u00D3", "O"); |
290 | 4 | characterSubstitutions.put("\u00D4", "O"); |
291 | 4 | characterSubstitutions.put("\u00D5", "O"); |
292 | 4 | characterSubstitutions.put("\u00D6", "O"); |
293 | 4 | characterSubstitutions.put("\u00D7", "x"); |
294 | 4 | characterSubstitutions.put("\u00D8", "O"); |
295 | 4 | characterSubstitutions.put("\u00D9", "U"); |
296 | 4 | characterSubstitutions.put("\u00DA", "U"); |
297 | 4 | characterSubstitutions.put("\u00DB", "U"); |
298 | 4 | characterSubstitutions.put("\u00DC", "U"); |
299 | 4 | characterSubstitutions.put("\u00DD", "Y"); |
300 | 4 | characterSubstitutions.put("\u00DE", "P"); |
301 | 4 | characterSubstitutions.put("\u00DF", "ss"); |
302 | |
|
303 | 4 | characterSubstitutions.put("\u00E0", "a"); |
304 | 4 | characterSubstitutions.put("\u00E1", "a"); |
305 | 4 | characterSubstitutions.put("\u00E2", "a"); |
306 | 4 | characterSubstitutions.put("\u00E3", "a"); |
307 | 4 | characterSubstitutions.put("\u00E4", "a"); |
308 | 4 | characterSubstitutions.put("\u00E5", "a"); |
309 | 4 | characterSubstitutions.put("\u00E6", "ae"); |
310 | 4 | characterSubstitutions.put("\u00E7", "c"); |
311 | 4 | characterSubstitutions.put("\u00E8", "e"); |
312 | 4 | characterSubstitutions.put("\u00E9", "e"); |
313 | 4 | characterSubstitutions.put("\u00EA", "e"); |
314 | 4 | characterSubstitutions.put("\u00EB", "e"); |
315 | 4 | characterSubstitutions.put("\u00EC", "i"); |
316 | 4 | characterSubstitutions.put("\u00ED", "i"); |
317 | 4 | characterSubstitutions.put("\u00EE", "i"); |
318 | 4 | characterSubstitutions.put("\u00EF", "i"); |
319 | |
|
320 | 4 | characterSubstitutions.put("\u00F0", "d"); |
321 | 4 | characterSubstitutions.put("\u00F1", "n"); |
322 | 4 | characterSubstitutions.put("\u00F2", "o"); |
323 | 4 | characterSubstitutions.put("\u00F3", "o"); |
324 | 4 | characterSubstitutions.put("\u00F4", "o"); |
325 | 4 | characterSubstitutions.put("\u00F5", "o"); |
326 | 4 | characterSubstitutions.put("\u00F6", "o"); |
327 | |
|
328 | 4 | characterSubstitutions.put("\u00F8", "o"); |
329 | 4 | characterSubstitutions.put("\u00F9", "u"); |
330 | 4 | characterSubstitutions.put("\u00FA", "u"); |
331 | 4 | characterSubstitutions.put("\u00FB", "u"); |
332 | 4 | characterSubstitutions.put("\u00FC", "u"); |
333 | 4 | characterSubstitutions.put("\u00FD", "y"); |
334 | 4 | characterSubstitutions.put("\u00FE", "p"); |
335 | 4 | characterSubstitutions.put("\u00FF", "y"); |
336 | 4 | } |
337 | |
} |