1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.seasar.tuigwaa.plugin.database;
17
18 import java.io.BufferedReader;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.io.UnsupportedEncodingException;
23 import java.net.URL;
24
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.struts.util.ResponseUtils;
31 import org.seasar.tuigwaa.cms.core.CmsRequest;
32 import org.seasar.tuigwaa.cms.core.CmsResponse;
33 import org.seasar.tuigwaa.cms.core.wiki.WikiContext;
34 import org.seasar.tuigwaa.database.DataTable;
35 import org.seasar.tuigwaa.database.function.criteria.CriteriaListFunction;
36 import org.seasar.tuigwaa.database.function.criteria.EqCriteriaFunction;
37 import org.seasar.tuigwaa.database.function.criteria.OrderCriteriaFunction;
38 import org.seasar.tuigwaa.model.DAOService;
39 import org.seasar.tuigwaa.model.common.EntityDAO;
40 import org.seasar.tuigwaa.model.core.TgwEntity;
41 import org.seasar.tuigwaa.plugin.AbstractTgwPlugin;
42 import org.seasar.tuigwaa.plugin.PluginException;
43 import org.seasar.tuigwaa.plugin.PluginRequest;
44 import org.seasar.tuigwaa.plugin.TgwPluginUtils;
45 import org.seasar.tuigwaa.system.Constants;
46 import org.seasar.tuigwaa.util.TgwContext;
47
48 import com.isenshi.util.CharUtil;
49 import com.isenshi.util.HtmlBuffer;
50 import com.isenshi.util.XMLStringBuffer;
51 import com.isenshi.util.extlib.StrutsUtil;
52
53 /***
54 * Tracback Plugin
55 *
56 * @author someda
57 * @see <a href="http://www.sixapart.com/pronet/docs/trackback_spec">TrackBack
58 * Technical Specification</a>
59 */
60 public class TrackbackPlugin extends AbstractTgwPlugin {
61
62 private Log log = LogFactory.getLog(getClass());
63
64 private static final String CHARSET_FILTER_ENCODING = "Windows-31J";
65
66 private static final String CHARSET_SYSTEM_ENCODING = "UTF-8";
67
68 private static final String PARAM_PAGENAME = getParameterName("trackback.name");
69
70 private static final int ERRORNO_SUCCESS = 0;
71
72 private static final int ERRORNO_FAILED = 1;
73
74 private static final int DEFAULT_DISPLAY_NUMBER = 10;
75
76
77 private static final String TRACKBACKPING_PARAM_URL = "url";
78
79 private static final String TRACKBACKPING_PARAM_TITLE = "title";
80
81 private static final String TRACKBACKPING_PARAM_EXCERPT = "excerpt";
82
83 private static final String TRACKBACKPING_PARAM_BLOGNAME = "blog_name";
84
85
86
87
88 private static final String ENTITY_TRACKBACK_PAGENAME = "pagename";
89
90 protected void initialize(CmsRequest request, CmsResponse response,
91 PluginRequest prequest) throws PluginException {
92 String siteName = request.getSiteName();
93 requireEntity(siteName, Trackback.class);
94 }
95
96 public String doHTMLView(CmsRequest request, CmsResponse response,
97 PluginRequest prequest) throws PluginException {
98
99 String pagename = request.getPage().getResource().getPath();
100 request.setParameter(PARAM_PAGENAME, pagename);
101
102 int number = DEFAULT_DISPLAY_NUMBER;
103 String[] args = prequest.getArgs();
104 if (args != null) {
105 try {
106 number = Integer.parseInt(args[0]);
107 } catch (NumberFormatException nfe) {
108 log.error("argment invalid and ignore it");
109 number = DEFAULT_DISPLAY_NUMBER;
110 }
111 }
112
113 WikiContext ctx = getConfiguration().getWikiContext();
114 String url = ctx.getPluginProxyURL(prequest.getName(), request)
115 .toString();
116 HtmlBuffer buf = new HtmlBuffer();
117 buf.appendBody(getMessage("trackback.trackback.url"));
118 buf.appendStartTag(HtmlBuffer.TAG_INPUT);
119 buf.appendAttribute("size", "120");
120 buf.appendAttribute("value", url);
121 buf.endTag();
122
123
124 TrackbackDAO dao = getTrackbackDAO();
125 DataTable dataTable = dao.getTrackbacks(request.getSiteName(),
126 pagename, null);
127
128 if (dataTable != null) {
129 boolean tagStart = false;
130 while (dataTable.hasNext() && number > 0) {
131
132 if (!tagStart) {
133 buf.appendStartTag("ul");
134 tagStart = true;
135 }
136
137 dataTable.next();
138 Trackback trackback = (Trackback) dataTable.getRowObject();
139
140 String title = trackback.getTitle();
141 String trackbackurl = trackback.getUrl();
142 String date = trackback.getModificationDate().toString();
143
144 buf.appendStartTag("li");
145 buf.appendBody("[" + date + "]");
146
147 if (title != null && !title.equals("")) {
148
149
150 buf.appendAnchor(trackbackurl, trackbackurl);
151
152 }
153 buf.endTag();
154 number--;
155 }
156 if (tagStart)
157 buf.endTag();
158 }
159 return buf.toString();
160 }
161
162 public String doAction(HttpServletRequest request,
163 HttpServletResponse response) {
164
165 String returnXML = null;
166
167 String method = request.getMethod();
168 String pagename = StrutsUtil.getURLDecodedParameter(request,
169 PARAM_PAGENAME);
170
171 if (!"post".equalsIgnoreCase(method)) {
172 return CharUtil.urlDecode(pagename);
173 }
174
175 String url = request.getParameter(TRACKBACKPING_PARAM_URL);
176
177 if (url == null) {
178 String msg = TRACKBACKPING_PARAM_URL + " must be given.";
179 log.error(msg);
180 returnXML = generateReturnXML(ERRORNO_FAILED, msg);
181 } else {
182 if (!isContainsUrl(url, pagename, request)) {
183
184 String msg = "source URL is invalid or doesn't contain this URL as contents.";
185 log.error(msg);
186 returnXML = generateReturnXML(ERRORNO_FAILED, msg);
187 } else {
188 String siteName = TgwContext.getSiteName();
189
190
191 log
192 .info("trackback Content-Type : "
193 + request.getContentType());
194
195 String title = request.getParameter(TRACKBACKPING_PARAM_TITLE);
196 String blogname = request
197 .getParameter(TRACKBACKPING_PARAM_BLOGNAME);
198 String excerpt = request
199 .getParameter(TRACKBACKPING_PARAM_EXCERPT);
200
201 try {
202 title = new String(title.getBytes(CHARSET_FILTER_ENCODING),
203 CHARSET_SYSTEM_ENCODING);
204 blogname = new String(blogname
205 .getBytes(CHARSET_FILTER_ENCODING),
206 CHARSET_SYSTEM_ENCODING);
207 excerpt = new String(excerpt
208 .getBytes(CHARSET_FILTER_ENCODING),
209 CHARSET_SYSTEM_ENCODING);
210
211 log.info("=------------------- after ------------------");
212 log.info("title :" + title + " blogname :" + blogname);
213 log.info("excerpt " + excerpt);
214 } catch (UnsupportedEncodingException uee) {
215 uee.printStackTrace();
216 }
217
218
219 try {
220 Trackback bean = getTrackbackBean(siteName, pagename, url,
221 title, blogname, excerpt);
222 getTrackbackDAO().save(bean);
223 returnXML = generateReturnXML(ERRORNO_SUCCESS, null);
224 } catch (Exception e) {
225 String msg = "sorry, storing trackback ping data failed.";
226 log.error(msg);
227 returnXML = generateReturnXML(ERRORNO_FAILED, msg);
228 }
229 }
230 }
231 response.setContentType("text/xml;charset=UTF-8");
232 try {
233 response.getWriter().write(returnXML);
234 } catch (IOException ioe) {
235 ioe.printStackTrace();
236 }
237 return null;
238 }
239
240 private String generateReturnXML(int errorno, String message) {
241
242 XMLStringBuffer buf = new XMLStringBuffer();
243 buf.appendXMLDeclaration("UTF-8", null);
244 buf.setTab(false);
245 buf.appendStartTag("response");
246
247 buf.appendStartTag("error");
248 buf.setNewline(false);
249 buf.appendBody(String.valueOf(errorno));
250 if (message != null && !message.equals("")) {
251 buf.setNewline(true);
252 buf.endTag();
253 buf.appendStartTag("message");
254 buf.setNewline(false);
255 buf.appendBody(message);
256 }
257 buf.setNewline(true);
258 buf.endAllTags();
259 return buf.toString();
260 }
261
262 private boolean isContainsUrl(String url, String pagename,
263 HttpServletRequest request) {
264
265 boolean containsUrl = false;
266 String serverName = request.getServerName();
267 log.info("trackback request comes from " + url + " to " + serverName);
268 try {
269 URL srcUrl = new URL(url);
270 InputStream is = srcUrl.openStream();
271 BufferedReader br = new BufferedReader(new InputStreamReader(is));
272 while (true) {
273 String line = br.readLine();
274 if (line == null)
275 break;
276 if (line.indexOf(serverName) != -1) {
277 containsUrl = true;
278 break;
279 }
280 }
281 br.close();
282 is.close();
283 } catch (IOException ioe) {
284 log.error("error occured during reading URL : " + url);
285 }
286 containsUrl = true;
287 return containsUrl;
288 }
289
290 private Trackback getTrackbackBean(String siteName, String pagename,
291 String url, String title, String blogName, String excerpt)
292 throws PluginException {
293
294 Trackback trackback = new Trackback();
295
296
297 DataTable dataTable = getTrackbackDAO().getTrackbacks(siteName,
298 pagename, url);
299 if (dataTable.hasNext()) {
300 dataTable.next();
301 Trackback aTrackback = (Trackback) dataTable.getRowObject();
302 trackback.setId(aTrackback.getId());
303 }
304
305 trackback.setPagename(pagename);
306 trackback.setUrl(url.replaceAll("<", "<").replaceAll(">", ">"));
307
308 if (title != null && !title.equals(""))
309 trackback.setTitle(ResponseUtils.filter(title));
310 if (blogName != null && !blogName.equals(""))
311 trackback.setBlogName(ResponseUtils.filter(blogName));
312 if (excerpt != null && !excerpt.equals(""))
313 trackback.setExcerpt(ResponseUtils.filter(excerpt));
314
315 return trackback;
316 }
317
318 private TrackbackDAO getTrackbackDAO() throws PluginException {
319 String siteName = TgwContext.getSiteName();
320
321 String entityName = TgwPluginUtils.toPluginEntityName(Trackback.class);
322 TgwEntity entity = getEntity(siteName, entityName);
323 if (entity == null) {
324 entity = requireEntity(siteName, Trackback.class);
325 }
326
327 return new TrackbackDAO(entity);
328 }
329
330 class TrackbackDAO {
331
332 DAOService daoService = (DAOService) getService(DAOService.class);
333
334 EntityDAO dao;
335
336 TrackbackDAO(TgwEntity trackback) {
337 dao = daoService.getDAO(trackback);
338 }
339
340 void save(Trackback trackback) {
341 dao.saveOrUpdate(trackback);
342 }
343
344 DataTable getTrackbacks(String siteName, String pageName, String url) {
345 CriteriaListFunction function = new CriteriaListFunction();
346 EqCriteriaFunction eq = new EqCriteriaFunction(
347 ENTITY_TRACKBACK_PAGENAME, pageName);
348 OrderCriteriaFunction order = new OrderCriteriaFunction(
349 Constants.ENTITY_BUILTIN_MODIFICATIONDATE, null, true);
350 function.addFunction(eq);
351 function.addFunction(order);
352 if (url != null) {
353 EqCriteriaFunction urleq = new EqCriteriaFunction(
354 TRACKBACKPING_PARAM_URL, url);
355 function.addFunction(urleq);
356 }
357 return getDataTable(siteName, Trackback.class, function);
358 }
359 }
360 }