001package dk.netarkivet.harvester.webinterface.servlet;
002
003import java.io.IOException;
004import java.io.OutputStream;
005import java.util.ArrayList;
006import java.util.List;
007
008import javax.servlet.ServletConfig;
009import javax.servlet.ServletException;
010import javax.servlet.http.HttpServlet;
011import javax.servlet.http.HttpServletRequest;
012import javax.servlet.http.HttpServletResponse;
013import javax.servlet.http.HttpSession;
014
015import org.slf4j.Logger;
016import org.slf4j.LoggerFactory;
017
018import com.antiaction.common.servlet.AutoIncrement;
019import com.antiaction.common.servlet.PathMap;
020
021public class HistoryServlet extends HttpServlet implements ResourceManagerAbstract {
022
023    /**
024     * UID
025     */
026    private static final long serialVersionUID = -7452707006494237017L;
027
028    /** The logger for this class. */
029    private static final Logger LOG = LoggerFactory.getLogger(HistoryServlet.class);
030
031    public static NASEnvironment environment;
032
033    public static PathMap<Resource> pathMap;
034
035    protected AutoIncrement resourceAutoInc = new AutoIncrement();
036
037    @Override
038    public void init(ServletConfig servletConfig) throws ServletException {
039        super.init(servletConfig);
040
041        environment = new NASEnvironment(getServletContext(), servletConfig);
042        environment.start();
043
044        pathMap = new PathMap<Resource>();
045
046        IndexResource indexResource = new IndexResource();
047        indexResource.resources_init(environment);
048        indexResource.resources_add(this);
049
050        JobResource jobResource = new JobResource();
051        jobResource.resources_init(environment);
052        jobResource.resources_add(this);
053    }
054
055    public int resource_add(ResourceAbstract resources, String path,
056            boolean bSecured) {
057        int resource_id = resourceAutoInc.getId();
058        Resource resource = new Resource();
059        resource.resource_id = resource_id;
060        resource.resources = resources;
061        resource.bSecured = bSecured;
062        pathMap.add(path, resource);
063        return resource_id;
064    }
065
066    /*
067     * (non-Javadoc)
068     * 
069     * @see javax.servlet.GenericServlet#destroy()
070     */
071    @Override
072    public void destroy() {
073        if (environment != null) {
074            environment.cleanup();
075            environment = null;
076        }
077        LOG.info("{} destroyed.", this.getClass().getName());
078        super.destroy();
079    }
080
081    /*
082     * (non-Javadoc)
083     * 
084     * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest
085     * , javax.servlet.http.HttpServletResponse)
086     */
087    @Override
088    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
089        HttpSession session = req.getSession();
090        try {
091            NASUser current_user = null;
092
093            // If we have a valid session look for an already logged in current
094            // user.
095            if (session != null) {
096                current_user = (NASUser) session.getAttribute("user");
097            }
098
099            // Look for cookies in case of no current user in session.
100            if (current_user == null && session != null && session.isNew()) {
101                // TODO
102                //current_user = environment.loginHandler.loginFromCookie(req, resp, session, this);
103            }
104
105            String action = req.getParameter("action");
106
107            // Logout, login or administration.
108            if (action != null && "logout".compareToIgnoreCase(action) == 0) {
109                // TODO
110                //environment.loginHandler.logoff(req, resp, session);
111            } else {
112                String pathInfo = req.getPathInfo();
113                if (pathInfo == null || pathInfo.length() == 0) {
114                    pathInfo = "/";
115                }
116
117                LOG.trace(req.getMethod() + " " + req.getPathInfo());
118
119                List<Integer> numerics = new ArrayList<Integer>();
120                Resource resource = pathMap.get(pathInfo, numerics);
121
122                if (resource != null) {
123                    if (resource.bSecured && current_user == null) {
124                        // TODO
125                        //environment.loginHandler.loginFromForm(req, resp, session, this);
126                        resp.sendError(HttpServletResponse.SC_UNAUTHORIZED, pathInfo);
127                    } else {
128                        resource.resources.resource_service(this.getServletContext(), current_user, req, resp, resource.resource_id, numerics, pathInfo);
129                    }
130                } else {
131                    resp.sendError(HttpServletResponse.SC_NOT_FOUND, pathInfo);
132                }
133            }
134        } catch (Throwable t) {
135            LOG.error(t.toString(), t);
136            StringBuilder sb = new StringBuilder();
137            sb.append( "<!DOCTYPE html><html lang=\"en\"><head>" );
138            sb.append( "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">" );
139            sb.append( "<title>" );
140            sb.append( Integer.toString( HttpServletResponse.SC_INTERNAL_SERVER_ERROR ) );
141            sb.append( " Internal server error...</title>" );
142            sb.append( "</head><body><h1>" );
143            sb.append( Integer.toString( HttpServletResponse.SC_INTERNAL_SERVER_ERROR ) );
144            sb.append( " Internal server error..." );
145            sb.append( "</h1><pre>" );
146            throwable_stacktrace_dump( t, sb );
147            sb.append( "</pre></body></html>" );
148            resp.setContentType("text/html; charset=utf-8");
149            resp.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
150            OutputStream out = resp.getOutputStream();
151            out.write( sb.toString().getBytes( "UTF-8" ) );
152            out.flush();
153            out.close();
154            //resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, sb.toString());
155        }
156    }
157
158    public static void stacktrace_dump(StackTraceElement[] stackTraceElementArr, StringBuilder sb) {
159        StackTraceElement stackTraceElement;
160        String fileName;
161        if (stackTraceElementArr != null && stackTraceElementArr.length > 0) {
162            for (int i=0; i<stackTraceElementArr.length; ++i) {
163                stackTraceElement = stackTraceElementArr[i];
164                sb.append("\tat ");
165                sb.append(stackTraceElement.getClassName());
166                sb.append(".");
167                sb.append(stackTraceElement.getMethodName());
168                sb.append("(");
169                fileName = stackTraceElement.getFileName();
170                if (fileName != null) {
171                    sb.append(fileName);
172                    sb.append(":");
173                    sb.append(stackTraceElement.getLineNumber());
174                } else {
175                    sb.append("Unknown source");
176                }
177                sb.append(")");
178                sb.append("\n");
179            }
180        }
181    }
182
183    public static void throwable_stacktrace_dump(Throwable t, StringBuilder sb) {
184        String message;
185        if (t != null) {
186            sb.append(t.getClass().getName());
187            message = t.getMessage();
188            if (message != null) {
189                sb.append(": ");
190                sb.append(t.getMessage());
191            }
192            sb.append("\n");
193            stacktrace_dump(t.getStackTrace(), sb);
194            while ((t = t.getCause()) != null) {
195                sb.append("caused by ");
196                sb.append(t.getClass().getName());
197                message = t.getMessage();
198                if (message != null) {
199                    sb.append(": ");
200                    sb.append(t.getMessage());
201                }
202                sb.append("\n");
203                stacktrace_dump(t.getStackTrace(), sb);
204            }
205        }
206    }
207
208    public static class Resource {
209
210        public int resource_id;
211
212        public ResourceAbstract resources;
213
214        public boolean bSecured;
215
216    }
217
218}