📄 frikiservlet.java
字号:
package com.efsol.friki;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.stringtree.factory.Fetcher;
import org.stringtree.factory.FetcherHelper;
import org.stringtree.factory.Repository;
import org.stringtree.factory.flatfiles.DirectoryStringRepository;
import org.stringtree.factory.flatfiles.SuffixFilter;
import org.stringtree.factory.memory.MapStringRepository;
import org.stringtree.factory.resource.ResourceStringFetcher;
import org.stringtree.factory.resource.ResourceTractFetcher;
import org.stringtree.factory.resource.SuffixResourceFilter;
import org.stringtree.util.FileReadingUtils;
import org.stringtree.util.FileUtils;
import org.stringtree.util.FileWritingUtils;
import org.stringtree.util.PropertyFileUtils;
import org.stringtree.util.ResourceUtils;
import org.stringtree.util.StringUtils;
import org.stringtree.util.tract.Tract;
import java.util.*;
public class FrikiServlet extends HttpServlet
{
private static final String redirectFileName="config.txt";
private static final String settingsFileName="friki.prp";
private Model model;
private Policy policy;
private Map buttonModes;
private File tmpDir;
private File redirect;
private File baseDir = null;
private void storeBaseDir(String dir)
{
try
{
FileWritingUtils.writeFile(redirect, dir);
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void setPolicy(Policy policy, String name, Object value)
{
if (!policy.contains(name))
{
policy.put(name, value);
}
}
private void setPolicy(File dir)
{
baseDir = dir;
resetPolicy();
}
private void resetPolicy()
{
try
{
policy.setBaseDir(baseDir);
File propFile = new File(baseDir, settingsFileName);
System.out.println("Friki: looking for external config file '" + propFile + "'");
if (propFile.exists() && propFile.canRead())
{
System.out.println("Friki: reading external config file '" + propFile + "'");
Properties props = new Properties();
FileInputStream in = new FileInputStream(propFile);
props.load(in);
in.close();
policy.putAll(props);
}
setPolicy(policy, "repository-location", "pages");
setPolicy(policy, "template-location", "templates");
setPolicy(policy, "transform-spec", "wiki.transform");
setPolicy(policy, "button-spec", "buttons.prp");
setPolicy(policy, "intermap-spec", "intermap.txt");
if (!propFile.exists() || propFile.canWrite())
{
System.out.println("Friki: updating external config file '" + propFile + "'");
Properties props = new Properties();
props.putAll(policy.getMap());
FileOutputStream out = new FileOutputStream(propFile);
props.store(out, "Friki configuration properties");
out.close();
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
MapStringRepository context = new MapStringRepository();
PageRepository repository = new PageRepository(new FileRepository(policy));
DirectoryStringRepository templates = new DirectoryStringRepository(
policy.getFile("template-location"), new SuffixFilter(".tpl"));
ensureDefaults(new ResourceTractFetcher(this),
repository, policy.get("initialPages"), "dflPages/", "page", true);
ensureDefaults(new ResourceStringFetcher(this, new SuffixResourceFilter(".tpl")),
templates, policy.get("modes"), "", "template", false);
ensureExists(policy.getFile("transform-spec"), "wiki.transform");
ensureExists(policy.getFile("button-spec"), "buttons.prp");
ensureExists(policy.getFile("intermap-spec"), "intermap.txt");
ContentFilter filter = new ClassicToHTMLFilter(context, repository,
ClassicToHTMLFilter.loadRemoteDetails(policy.getFile("intermap-spec")), policy.getFile("transform-spec"));
Renderer renderer = new HTMLRenderer(filter, templates,
"<b>Sorry! can't @MODE@ page '@page.name@'</b>");
model = new Model(repository, renderer, filter, policy);
buttonModes = PropertyFileUtils.readPropertyFile(policy.getFile("button-spec"));
}
private void ensureExists(File dest, String resourceName)
{
if (!dest.exists())
{
try
{
FileWritingUtils.writeFile(dest, ResourceUtils.readResource(resourceName));
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private void ensureExists(Fetcher fetcher, Repository repository, String prefix, String name,
String type, boolean verbose)
{
if (!FetcherHelper.contains(repository, name))
{
String source = prefix + name;
Object item = fetcher.getObject(source);
if (item != null)
{
System.out.println("Initial " + type + " '" + name + "' missing, reinstalling from default.");
repository.put(name, item);
}
else if (verbose)
{
System.out.println("Initial " + type + " '" + name + "' missing, default not found.");
}
}
}
private void ensureDefaults(Fetcher fetcher, Repository repository, String list,
String prefix, String type, boolean verbose)
{
StringTokenizer tok = new StringTokenizer(list, ", ");
while (tok.hasMoreTokens())
{
String name = tok.nextToken();
ensureExists(fetcher, repository, prefix, name, type, verbose);
}
}
private void setRedirect(File check)
{
if (check.canRead())
{
String content = FileReadingUtils.readFile(check);
setBaseDir(content);
}
}
private void setBaseDir(String content)
{
File dir;
if ("*TMP*".equals(content))
{
dir = tmpDir;
}
else
{
dir = FileUtils.ensureDirectory(content);
}
if (dir.isDirectory() && dir.canWrite())
{
System.out.println("Friki: located external storage dir '" + dir + "'");
storeBaseDir(content);
setPolicy(dir);
}
}
public void init()
throws ServletException
{
tmpDir = (File)getServletContext().getAttribute("javax.servlet.context.tempdir");
policy = new Policy(tmpDir);
setPolicy(policy, "initialPages", "FrontPage PageFormatting SandBox FrankCarver EfficacySolutionsLimited RecentChanges ReadRequests");
setPolicy(policy, "dflPage", "FrontPage");
setPolicy(policy, "logReads", "false");
setPolicy(policy, "readLogPage", "ReadRequests");
setPolicy(policy, "logWrites", "true");
setPolicy(policy, "writeLogPage", "RecentChanges");
setPolicy(policy, "backupChanges", "true");
setPolicy(policy, "backupDir", "old");
setPolicy(policy, "modes", "view,edit,search,update,diff");
setPolicy(policy, "filterModes", "view,search,diff");
setPolicy(policy, "viewMode", "view");
setPolicy(policy, "editMode", "edit");
setPolicy(policy, "searchMode", "search");
setPolicy(policy, "diffMode", "diff");
setPolicy(policy, "updateMode", "update");
redirect = new File(tmpDir, redirectFileName);
setRedirect(redirect);
}
private void logLink(String dest, String pageName, String author, boolean diffs)
{
model.log(dest, pageName, author, diffs);
}
private void show(HttpServletResponse res, String pageName, String mode, String author)
throws IOException
{
res.setContentType("text/html");
Writer out = res.getWriter();
pageName = model.ensurePage(pageName);
mode = model.ensureMode(mode);
Tract page;
if (mode.equals(policy.get("searchMode")))
{
page = model.search(pageName);
}
else
if (mode.equals(policy.get("diffMode")))
{
page = model.get(pageName);
page.put("diff", model.diff(pageName));
}
else
{
page = model.get(pageName);
if (mode.equals(policy.get("viewMode"))
&& "true".equalsIgnoreCase(policy.get("logReads")))
{
logLink(policy.get("readLogPage"), pageName, author, false);
}
}
boolean filterpage = ! "false".equals(page.getAttribute("filter"));
String filtermodes = policy.get("filterModes");
boolean isFiltered = filterpage &&
filtermodes != null && filtermodes.indexOf(mode) >= 0;
model.render(page, mode, out, isFiltered);
out.flush();
}
private String getMode(HttpServletRequest req)
{
String mode = req.getServletPath();
// strip preceding path info from mode (if present)
int sep = mode.lastIndexOf("/");
if (sep > -1)
{
mode = mode.substring(sep);
}
if (mode==null || "".equals(mode) || "/".equals(mode))
{
mode = policy.get("viewMode");
}
else
{
mode = mode.substring(1);
}
return mode;
}
private String getEffectiveMode(String mode, HttpServletRequest req)
{
if ("button".equals(mode))
{
String param = req.getParameter("button");
mode = (String)buttonModes.get(param);
}
return mode;
}
private String getAuthor(HttpServletRequest req)
{
String ip = req.getRemoteAddr();
String host = req.getRemoteHost();
String from = req.getHeader("From");
boolean gotOne = false;
StringBuffer buf = new StringBuffer();
if (!StringUtils.isBlank(ip))
{
buf.append(ip);
gotOne = true;
}
if (!StringUtils.isBlank(host) && !host.equals(ip))
{
buf.append("(");
buf.append(host);
buf.append(")");
gotOne = true;
}
if (!StringUtils.isBlank(from))
{
if (gotOne)
{
buf.append(" ");
}
buf.append(from);
gotOne = true;
}
if (!gotOne)
{
buf.append("unknown");
}
return buf.toString();
}
public void doQueryRequest(String mode, HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
if (unconfigured(req, res)) return;
show(res, req.getQueryString(), mode, getAuthor(req));
}
public void doParameterRequest(String mode, HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
if (unconfigured(req, res)) return;
String page = req.getParameter("page");
String content = req.getParameter("content");
String author = getAuthor(req);
mode = getEffectiveMode(mode, req);
if (mode.equals("reset"))
{
resetPolicy();
mode = policy.get("viewMode");
}
if (mode.equals(policy.get("updateMode")))
{
model.update(page, content);
if ("true".equalsIgnoreCase(policy.get("logWrites")))
{
logLink(policy.get("writeLogPage"), page, author, true);
}
res.sendRedirect(policy.get("viewMode") + "?" + NamePreserver.escape(page));
}
else if (mode.equals(policy.get("searchMode")))
{
show(res, req.getParameter("pattern"), mode, author);
}
else
{
show(res, page, mode, author);
}
}
private boolean unconfigured(HttpServletRequest req, HttpServletResponse res)
throws IOException
{
boolean ret = false;
if(baseDir == null)
{
String dir = req.getParameter("dir");
if (!StringUtils.isBlank(dir))
{
setBaseDir(dir);
}
else
{
res.getWriter().write(ResourceUtils.readResource("config.html"));
ret = true;
}
}
return ret;
}
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
String mode = getMode(req);
if ("button".equals(mode))
{
doParameterRequest(mode, req, res);
}
else
{
doQueryRequest(mode, req, res);
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
doParameterRequest(getMode(req), req, res);
}
public String getServletInfo()
{
return "Friki :- Frank's Wiki";
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -