1 package net.sourceforge.blogentis.modules.actions;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.io.UnsupportedEncodingException;
26 import java.sql.Connection;
27 import java.util.Date;
28 import java.util.List;
29 import java.util.regex.Pattern;
30
31 import net.sourceforge.blogentis.om.Post;
32 import net.sourceforge.blogentis.om.PostPeer;
33 import net.sourceforge.blogentis.om.PostSectionPeer;
34 import net.sourceforge.blogentis.om.SectionPeer;
35 import net.sourceforge.blogentis.plugins.BlogPluginService;
36 import net.sourceforge.blogentis.plugins.base.IPostEditExtensionPoint;
37 import net.sourceforge.blogentis.turbine.BlogParameterParser;
38 import net.sourceforge.blogentis.turbine.BlogRunData;
39 import net.sourceforge.blogentis.turbine.SecureBlogAction;
40 import net.sourceforge.blogentis.utils.BlogConstants;
41 import net.sourceforge.blogentis.utils.JTidyService;
42 import net.sourceforge.blogentis.utils.LinkFactoryService;
43 import net.sourceforge.blogentis.utils.MappedConfiguration;
44 import net.sourceforge.blogentis.utils.StringUtils;
45
46 import org.apache.commons.logging.Log;
47 import org.apache.commons.logging.LogFactory;
48 import org.apache.torque.TorqueException;
49 import org.apache.torque.util.Transaction;
50 import org.apache.turbine.util.RunData;
51 import org.apache.velocity.context.Context;
52
53 public class PostMod
54 extends SecureBlogAction {
55 private static final Log log = LogFactory.getLog(PostMod.class);
56
57 private static final Pattern paraBegin = Pattern.compile("^<p>[\n\r]*");
58 private static final Pattern paraEnd = Pattern
59 .compile("[\n\r]*</p>[\n\r]*$");
60
61 private static abstract class Invoker {
62 abstract public void invoke(IPostEditExtensionPoint point,
63 BlogRunData data, Post p);
64 }
65
66 private Invoker invokePublication = new Invoker() {
67 public void invoke(IPostEditExtensionPoint point, BlogRunData data,
68 Post p) {
69 if (p.isNew()) {
70 point.postNew(data, p);
71 }
72 if (p.getPostType() == PostPeer.DRAFT_TYPE) {
73 p.setPostType(PostPeer.PUBLISHED_TYPE);
74 point
75 .postPublicationStatusChanged(data, p, PostPeer.DRAFT_TYPE);
76 } else {
77 point.postModified(data, p);
78 }
79 }
80 };
81 private Invoker invokeNew = new Invoker() {
82 public void invoke(IPostEditExtensionPoint point, BlogRunData data,
83 Post p) {
84 point.postNew(data, p);
85 }
86 };
87 private Invoker invokeModified = new Invoker() {
88 public void invoke(IPostEditExtensionPoint point, BlogRunData data,
89 Post p) {
90 point.postModified(data, p);
91 }
92 };
93
94 private String cleanupString(String orig, boolean removePara)
95 throws UnsupportedEncodingException {
96 String tmp = JTidyService.cleanupString(orig);
97 if (removePara) {
98 tmp = paraBegin.matcher(tmp).replaceFirst("");
99 tmp = paraEnd.matcher(tmp).replaceFirst("");
100 }
101 tmp = tmp.replaceFirst("[\n\r]+$", "");
102 return tmp;
103 }
104
105 private String makeFragment(String title) {
106 StringBuffer sb = new StringBuffer(title.length());
107 boolean dashExists = false;
108 for(int i = 0; i < title.length(); i++) {
109 char c = title.charAt(i);
110 if (Character.isLetterOrDigit(c)) {
111 if (dashExists && sb.length() > 0)
112 sb.append('-');
113 sb.append(Character.toLowerCase(c));
114 dashExists = false;
115 } else {
116 dashExists = true;
117 }
118 }
119 return sb.toString();
120 }
121
122 private void processInput(RunData data, Post p) {
123 if (data.getParameters().getString("convertBreaks", null) != null) {
124 p.setFullText(StringUtils.convertBreaks(p.getFullText()));
125 }
126 if (data.getParameters().getString("cleanupHTML", null) != null) {
127 try {
128 p.setShortDescription(cleanupString(p.getShortDescription(),
129 true));
130 p.setFullText(cleanupString(p.getFullText(), false));
131 } catch (UnsupportedEncodingException e) {
132 log.error(e);
133 }
134 }
135 }
136
137 protected Post getPost(RunData data) {
138 BlogParameterParser pp = (BlogParameterParser)data.getParameters();
139 Post p = pp.getPost();
140 if (p == null)
141 data.setMessage("Could not retrieve post");
142 if (p.getBlogId() != pp.getBlog().getBlogId()) {
143 data.setMessage("Post belong to other blog.");
144 return null;
145 }
146 return p;
147 }
148
149 protected Post retrieveFromRequest(Post orig, RunData data)
150 throws TorqueException {
151 BlogParameterParser pp = (BlogParameterParser)data.getParameters();
152 orig.setBlogId(pp.getBlog().getBlogId());
153 orig.setTitle(pp.getString("title", null));
154 orig.setShortDescription(pp.getString("shortDescription", null));
155 orig.setFullText(pp.getString("fullText", null));
156 String f = pp.getString("uriFragment", "");
157 f = makeFragment(f);
158 if (f.length() == 0)
159 f = makeFragment(orig.getTitle());
160 orig.setUriFragment(f);
161 MappedConfiguration prop = orig.getProperties();
162 prop.setProperty("allowComments", pp.getBooleanObject("allowComments",
163 Boolean.FALSE));
164 processInput(data, orig);
165 return orig;
166 }
167
168 protected void redirectToPost(RunData data, Post p) {
169 BlogParameterParser pp = (BlogParameterParser)data.getParameters();
170 data.setRedirectURI(LinkFactoryService.getLink().setBlog(pp.getBlog())
171 .setPost(p).toString());
172 }
173
174 protected void setAuthor(Post post, RunData data)
175 throws Exception {
176 post.setAuthorId(data.getUser().getName());
177 }
178
179 public void doDraft(RunData data, Context context)
180 throws Exception {
181 Post p = retrieveFromRequest(new Post(), data);
182 p.setPostType(PostPeer.DRAFT_TYPE);
183 setAuthor(p, data);
184 p.setPostedTime(new Date());
185 fixSectionsAndCommit(data, p, invokeNew);
186 redirectToPost(data, p);
187 }
188
189 public void doUpdate(RunData data, Context context)
190 throws Exception {
191 Post p = retrieveFromRequest(getPost(data), data);
192 fixSectionsAndCommit(data, p, invokeModified);
193 redirectToPost(data, p);
194 }
195
196 public void doPublish(RunData data, Context context)
197 throws Exception {
198 BlogParameterParser pp = (BlogParameterParser)data.getParameters();
199 Post p = null;
200 if (pp.getPost() != null) {
201 p = getPost(data);
202 } else {
203 p = new Post();
204 setAuthor(p, data);
205 }
206 p = retrieveFromRequest(p, data);
207
208 p.setPostedTime(new Date());
209 fixSectionsAndCommit(data, p, invokePublication);
210 redirectToPost(data, p);
211 }
212
213 public void doUnpublish(RunData data, Context context)
214 throws Exception {
215 Post p = getPost(data);
216 if (p != null) {
217 int oldType = p.getPostType();
218 p.setPostType(PostPeer.DRAFT_TYPE);
219 if (oldType == PostPeer.PUBLISHED_TYPE) {
220 BlogRunData d = (BlogRunData)data;
221 IPostEditExtensionPoint pExt = (IPostEditExtensionPoint)BlogPluginService
222 .locateExtensionPoint(d.getBlog(),
223 IPostEditExtensionPoint.class);
224 if (pExt != null) {
225 pExt.postPublicationStatusChanged(d, p, oldType);
226 }
227 }
228 p.save();
229 }
230 }
231
232 public void doDelete(RunData data, Context context)
233 throws Exception {
234 BlogParameterParser pp = (BlogParameterParser)data.getParameters();
235 Post p = getPost(data);
236 if (p != null && !p.isNew()) {
237 PostPeer.doDelete(p.getPrimaryKey());
238 BlogRunData d = (BlogRunData)data;
239 IPostEditExtensionPoint pExt = (IPostEditExtensionPoint)BlogPluginService
240 .locateExtensionPoint(d.getBlog(),
241 IPostEditExtensionPoint.class);
242 if (pExt != null)
243 pExt.postDeleted(d, p);
244 data.setRedirectURI(LinkFactoryService.getLink()
245 .setBlog(pp.getBlog()).toString());
246 }
247 }
248
249 public void doPerform(RunData data, Context context)
250 throws Exception {
251 data.setMessage("Requested action not found.");
252 }
253
254 protected void makeSections(Connection con, RunData data, Post post)
255 throws Exception {
256 BlogParameterParser pp = (BlogParameterParser)data.getParameters();
257 List sections = java.util.Arrays.asList(pp.getStrings("sections",
258 new String[] {}));
259 List l = SectionPeer.retrieveByPKs(sections);
260 post.replaceSections(con, l);
261 }
262
263 protected void fixSectionsAndCommit(RunData data, Post post, Invoker invoke)
264 throws Exception {
265 Connection con = Transaction.begin(PostSectionPeer.DATABASE_NAME);
266 try {
267 BlogRunData d = (BlogRunData)data;
268 IPostEditExtensionPoint pExt = (IPostEditExtensionPoint)BlogPluginService
269 .locateExtensionPoint(d.getBlog(),
270 IPostEditExtensionPoint.class);
271 if (pExt != null && invoke != null) {
272 invoke.invoke(pExt, d, post);
273 }
274 makeSections(con, data, post);
275 if (post.isModified()) {
276 post.save(con);
277 }
278 Transaction.commit(con);
279 } catch (Exception e) {
280 if (con != null)
281 Transaction.safeRollback(con);
282 throw e;
283 }
284 }
285
286 protected String[] getPermissions() {
287
288 return new String[] {BlogConstants.PERM_WRITE_POSTS};
289 }
290 }