libreccm-legacy/ccm-core/src/com/arsdigita/versioning/VersioningServlet.java

268 lines
8.7 KiB
Java
Executable File

/*
* Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package com.arsdigita.versioning;
import com.arsdigita.kernel.Kernel;
import com.arsdigita.persistence.AbstractTransactionListener;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.OID;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.persistence.TransactionContext;
import com.arsdigita.util.Assert;
import com.arsdigita.versioning.DevSupport.NodeFilter;
import com.arsdigita.web.BaseServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
/**
* This servlet, along with a couple of helper JSPs, is used for debugging.
*
* @author Vadim Nasardinov (vadimn@redhat.com)
* @since 2003-07-01
* @version $Revision: #11 $ $Date: 2004/08/16 $
**/
public final class VersioningServlet extends BaseServlet {
private final static Logger s_log =
Logger.getLogger(VersioningServlet.class);
private final static String CMD = "cmd";
private final static String OID = "oid";
private final static String TITLE = "title";
private final static String JSP_DIR = "/themes/heirloom/packages/versioning/";
@Override
public void doService(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
if ( !Versioning.getConfig().isDebugUIEnabled() ) {
throw new ServletException("this service is disabled");
}
TransactionContext txn = SessionManager.getSession().
getTransactionContext();
txn.addTransactionListener(new AbstractTransactionListener() {
@Override
public void beforeCommit(TransactionContext txn) {
Assert.fail("uncommittable transaction");
}
});
Kernel.getContext().getTransaction().setCommitRequested(false);
String cmd = req.getParameter(CMD);
if ( cmd == null || "typeSearch".equals(cmd) ) {
mainPage(req, resp);
} else if ( "showTxns".equals(cmd) ) {
txnsPage(req, resp);
} else if ( "rollback".equals(cmd) ) {
rollbackPage(req, resp);
} else if ( "graph".equals(cmd) ) {
versioningGraphPage(req, resp);
} else {
throw new ServletException("unknown cmd=" + cmd);
}
}
private RequestDispatcher getDispatcher(String path) {
return getServletContext().getRequestDispatcher(path);
}
private void mainPage(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
VersionedObjects versionedObjects =
new VersionedObjectsImpl(req.getParameter("objectType"));
req.setAttribute(TITLE, "Versioning Log");
req.setAttribute("versionedObjects", versionedObjects);
getDispatcher(JSP_DIR + "main.jsp").forward(req, resp);
}
private void txnsPage(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String serOID = getParam(req, OID);
OID oid = (OID) Adapter.deserialize(serOID, Types.OID);
String tagged = req.getParameter("tagged");
TransactionCollection txnColl = null;
if ( tagged != null && "yes".equals(tagged) ) {
txnColl = Versions.getTaggedTransactions(oid);
} else {
txnColl = Versions.getTransactions(oid);
}
req.setAttribute(TITLE, "Transactions");
req.setAttribute("txns", txnColl);
req.setAttribute(OID, oid);
req.setAttribute("encodedOID", URLEncoder.encode(serOID));
getDispatcher(JSP_DIR + "txns.jsp").forward(req, resp);
}
private void rollbackPage(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
OID oid = (OID) Adapter.deserialize(getParam(req, OID), Types.OID);
BigInteger txnID = new BigInteger(getParam(req, "txnID"));
RollbackLogger rb = new RollerBacker(oid, txnID);
req.setAttribute("logger", rb);
getDispatcher(JSP_DIR + "rollback.jsp").forward(req, resp);
}
private void versioningGraphPage(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String graphType = getParam(req, "graphType");
req.setAttribute(TITLE, "Versioning Graph");
GraphPrinter printer = new GraphPrinterImpl(new NodeFilter() {
public boolean test(String qName, boolean isReachable) {
return isReachable && qName != null && qName.startsWith("com");
}
});
req.setAttribute("graphPrinter", printer);
getDispatcher(JSP_DIR + "graph.jsp").forward(req, resp);
}
private static String getParam(HttpServletRequest req, String name)
throws ServletException {
String result = req.getParameter(name);
if ( result == null ) {
throw new ServletException(name + " was not supplied");
}
return result;
}
/**
* <p>An iterator over a collection of versioned oids. You should not need
* to use this interface.</p>
*
* @see VersioningServlet
**/
public interface VersionedObjects {
OID getOID();
boolean hasNext();
Object next();
int size();
}
/**
* <p>Logs operations performed during rollback. The output goes to the
* writer specified via {@link
* VersioningServlet.RollbackLogger#setWriter(Writer)}. You should not need
* to use this interface. </p>
*
* @see VersioningServlet
*/
public interface RollbackLogger {
OID getOID();
BigInteger getTxnID();
void setWriter(Writer writer);
void rollback();
void printException(Throwable throwable) throws ServletException;
}
/**
* <p>Prints the versioning dependency graph to the specified writer. You
* should not need to use this interface. </p>
*
* @see VersioningServlet
**/
public interface GraphPrinter {
void setWriter(Writer writer);
void printGraph();
}
private static class VersionedObjectsImpl
implements Constants, VersionedObjects {
private List m_oids;
private Iterator m_iter;
private OID m_curOID;
public VersionedObjectsImpl(String type) {
DataCollection dc = SessionManager.getSession().retrieve(CHANGE_DATA_TYPE);
dc.addFilter(OBJ_ID + " like '%" + type + "%'");
Set oids = new HashSet();
while ( dc.next() ) {
oids.add(dc.get(OBJ_ID));
}
m_oids = new ArrayList(oids);
Collections.sort(m_oids);
m_iter = m_oids.iterator();
}
public boolean hasNext() {
return m_iter.hasNext();
}
public Object next() {
String next = (String) m_iter.next();
m_curOID = (OID) Adapter.deserialize(next, Types.OID);
return next;
}
public int size() {
return m_oids.size();
}
public OID getOID() {
return m_curOID;
}
}
private static class GraphPrinterImpl implements GraphPrinter {
private final NodeFilter m_filter;
private PrintWriter m_writer;
GraphPrinterImpl(NodeFilter filter) {
m_filter = filter;
}
public void setWriter(Writer writer) {
m_writer = new PrintWriter(writer);
}
public void printGraph() {
DevSupport.versioningGraphToDot(m_filter, m_writer);
}
}
}