001package dk.netarkivet.harvester.webinterface.servlet;
002
003import java.io.BufferedReader;
004import java.io.IOException;
005import java.io.StringReader;
006import java.util.ArrayList;
007import java.util.HashMap;
008import java.util.Iterator;
009import java.util.LinkedList;
010import java.util.List;
011import java.util.Map;
012
013import javax.servlet.ServletContext;
014import javax.servlet.ServletOutputStream;
015import javax.servlet.http.HttpServletRequest;
016import javax.servlet.http.HttpServletResponse;
017
018import com.antiaction.common.filter.Caching;
019import com.antiaction.common.templateengine.TemplateBuilderFactory;
020import com.antiaction.common.templateengine.TemplateBuilderPlaceHolder;
021import com.antiaction.common.templateengine.TemplatePlaceHolder;
022
023import dk.netarkivet.common.CommonSettings;
024import dk.netarkivet.common.Constants;
025import dk.netarkivet.common.utils.Settings;
026import dk.netarkivet.harvester.datamodel.HarvestChannel;
027import dk.netarkivet.harvester.webinterface.servlet.NASEnvironment.StringMatcher;
028
029public class IndexResource implements ResourceAbstract {
030
031    private NASEnvironment environment;
032
033    protected int R_INDEX = -1;
034
035    protected int R_CONFIG = -1;
036
037    @Override
038    public void resources_init(NASEnvironment environment) {
039        this.environment = environment;
040    }
041
042    @Override
043    public void resources_add(ResourceManagerAbstract resourceManager) {
044        R_INDEX = resourceManager.resource_add(this, "/", false);
045        R_CONFIG = resourceManager.resource_add(this, "/config/", false);
046    }
047
048    @Override
049    public void resource_service(ServletContext servletContext, NASUser nas_user, HttpServletRequest req, HttpServletResponse resp, int resource_id, List<Integer> numerics, String pathInfo) throws IOException {
050        if (NASEnvironment.contextPath == null) {
051            NASEnvironment.contextPath = req.getContextPath();
052        }
053        if (NASEnvironment.servicePath == null) {
054            NASEnvironment.servicePath = req.getContextPath() + req.getServletPath() + "/";
055        }
056        String method = req.getMethod().toUpperCase();
057        if (resource_id == R_INDEX) {
058            if ("GET".equals(method)) {
059                index(req, resp, numerics);
060            }
061        }
062        if (resource_id == R_CONFIG) {
063            if ("GET".equals(method) || "POST".equals(method)) {
064                config(req, resp, numerics);
065            }
066        }
067    }
068
069    public static class HarvestChannelStructure {
070        public HarvestChannel hc;
071        public List<Heritrix3JobMonitor> h3JobList = new ArrayList<Heritrix3JobMonitor>();
072        public HarvestChannelStructure(HarvestChannel hc) {
073            this.hc = hc;
074        }
075    }
076
077    public void index(HttpServletRequest req, HttpServletResponse resp, List<Integer> numerics) throws IOException {
078        resp.setContentType("text/html; charset=UTF-8");
079        ServletOutputStream out = resp.getOutputStream();
080
081        Caching.caching_disable_headers(resp);
082
083        TemplateBuilderFactory<MasterTemplateBuilder> tplBuilder = TemplateBuilderFactory.getInstance(environment.templateMaster, "master.tpl", "UTF-8", MasterTemplateBuilder.class);
084        MasterTemplateBuilder masterTplBuilder = tplBuilder.getTemplateBuilder();
085
086        StringBuilder sb = new StringBuilder();
087
088        List<Heritrix3JobMonitor> h3JobsList = environment.h3JobMonitorThread.getRunningH3Jobs();
089        Heritrix3JobMonitor h3Job;
090
091        sb.append("<a href=\"");
092        sb.append(NASEnvironment.servicePath);
093        sb.append("config/");
094        sb.append("\" class=\"btn btn-default\">");
095        sb.append("Configure");
096        sb.append("</a>");
097        sb.append("<br />\n");
098        sb.append("<br />\n");
099
100        List<HarvestChannelStructure> hcList = new ArrayList<HarvestChannelStructure>();
101        Map<String, HarvestChannelStructure> hcMap = new HashMap<String, HarvestChannelStructure>();
102
103        Iterator<HarvestChannel> hcIter = Heritrix3JobMonitorThread.harvestChannelDAO.getAll(true);
104        HarvestChannel hc;
105        HarvestChannelStructure hcs;
106        while (hcIter.hasNext()) {
107            hc = hcIter.next();
108            hcs = new HarvestChannelStructure(hc);
109            hcList.add(hcs);
110            hcMap.put(hc.getName(), hcs);
111        }
112
113        Iterator<Heritrix3JobMonitor> j3JobIter = h3JobsList.iterator();
114        while (j3JobIter.hasNext()) {
115            h3Job = j3JobIter.next();
116            if (!h3Job.bInitialized) {
117                h3Job.init();
118            }
119            hcs = hcMap.get(h3Job.job.getChannel());
120            hcs.h3JobList.add(h3Job);
121        }
122
123        for (int i=0; i<hcList.size(); ++i) {
124            hcs = hcList.get(i);
125            sb.append("<h5>");
126            sb.append(hcs.hc.getName());
127            if (hcs.hc.isDefault()) {
128                sb.append("*");
129            }
130            sb.append("&nbsp;");
131            sb.append("(type=");
132            if (hcs.hc.isSnapshot()) {
133                sb.append("snapshot");
134            } else {
135                sb.append("focused");
136            }
137            sb.append(")");
138            sb.append("</h5>\n");
139            if (hcs.h3JobList.size() > 0) {
140                for (int j=0; j<hcs.h3JobList.size(); ++j) {
141                    h3Job = hcs.h3JobList.get(j);
142                    if (j > 0) {
143                        sb.append("&nbsp;");
144                    }
145                    sb.append("<a href=\"");
146                    sb.append(NASEnvironment.servicePath);
147                    sb.append("job/");
148                    sb.append(h3Job.jobId);
149                    sb.append("/");
150                    sb.append("\" class=\"btn btn-default\">");
151                    sb.append(h3Job.jobId);
152                    long lines = (h3Job.idxFile.length() / 8) - 1;
153                    if (lines > 0) {
154                        sb.append(" (");
155                        sb.append(lines);
156                        sb.append(")");
157                    }
158                    sb.append("</a>\n");
159                }
160            } else {
161                sb.append("<p>No jobs running for this channel.</p>");
162            }
163        }
164
165        if (masterTplBuilder.titlePlace != null) {
166            masterTplBuilder.titlePlace.setText("H3 remote access");
167        }
168
169        if (masterTplBuilder.headingPlace != null) {
170            masterTplBuilder.headingPlace.setText("H3 remote access");
171        }
172
173        if (masterTplBuilder.contentPlace != null) {
174            masterTplBuilder.contentPlace.setText(sb.toString());
175        }
176
177        if (masterTplBuilder.versionPlace != null) {
178            masterTplBuilder.versionPlace.setText(Constants.getVersionString());
179        }
180
181        if (masterTplBuilder.environmentPlace != null) {
182            masterTplBuilder.environmentPlace.setText(Settings.get(CommonSettings.ENVIRONMENT_NAME));
183        }
184
185        masterTplBuilder.write(out);
186
187        out.flush();
188        out.close();
189    }
190
191    public static class ConfigTemplateBuilder extends MasterTemplateBuilder {
192
193        @TemplateBuilderPlaceHolder("enabledhosts")
194        public TemplatePlaceHolder enabledhostsPlace;
195
196    }
197
198    public void config(HttpServletRequest req, HttpServletResponse resp, List<Integer> numerics) throws IOException {
199        resp.setContentType("text/html; charset=UTF-8");
200        ServletOutputStream out = resp.getOutputStream();
201
202        Caching.caching_disable_headers(resp);
203
204        TemplateBuilderFactory<ConfigTemplateBuilder> tplBuilder = TemplateBuilderFactory.getInstance(environment.templateMaster, "h3config.tpl", "UTF-8", ConfigTemplateBuilder.class);
205        ConfigTemplateBuilder configTplBuilder = tplBuilder.getTemplateBuilder();
206
207        StringBuilder sb = new StringBuilder();
208        StringBuilder enabledhostsSb = new StringBuilder();
209
210        String method = req.getMethod().toUpperCase();
211        if ("POST".equals(method)) {
212            String enabledhostsStr = req.getParameter("enabledhosts");
213            String tmpStr;
214            if (enabledhostsStr != null) {
215                BufferedReader reader = new BufferedReader(new StringReader(enabledhostsStr));
216                List<String> enabledhostsList = new LinkedList<String>();
217                while ((tmpStr = reader.readLine()) != null) {
218                    enabledhostsList.add(tmpStr);
219                }
220                reader.close();
221                environment.replaceH3HostnamePortRegexList(enabledhostsList);
222                environment.h3JobMonitorThread.updateH3HostnamePortFilter();
223            }
224        }
225
226        synchronized (environment.h3HostPortAllowRegexList) {
227            StringMatcher stringMatcher;
228            for (int i=0; i<environment.h3HostPortAllowRegexList.size(); ++i) {
229                stringMatcher = environment.h3HostPortAllowRegexList.get(i);
230                enabledhostsSb.append(stringMatcher.str);
231                enabledhostsSb.append("\n");
232            }
233        }
234
235        synchronized (environment.h3JobMonitorThread.h3HostnamePortEnabledList) {
236            sb.append("H3 crawllog caching enabled for:");
237            sb.append("<br />\n");
238            sb.append("<br />\n");
239            if (environment.h3JobMonitorThread.h3HostnamePortEnabledList.size() > 0) {
240                for (int i=0; i<environment.h3JobMonitorThread.h3HostnamePortEnabledList.size(); ++i) {
241                    sb.append(environment.h3JobMonitorThread.h3HostnamePortEnabledList.get(i));
242                    sb.append("<br />\n");
243                }
244            } else {
245                sb.append("No host enabled.");
246                sb.append("<br />\n");
247            }
248        }
249        sb.append("<br />\n");
250        synchronized (environment.h3JobMonitorThread.h3HostnamePortDisabledList) {
251            sb.append("H3 crawllog caching disabled for:");
252            sb.append("<br />\n");
253            sb.append("<br />\n");
254            if (environment.h3JobMonitorThread.h3HostnamePortDisabledList.size() > 0) {
255                for (int i=0; i<environment.h3JobMonitorThread.h3HostnamePortDisabledList.size(); ++i) {
256                    sb.append(environment.h3JobMonitorThread.h3HostnamePortDisabledList.get(i));
257                    sb.append("<br />\n");
258                }
259            } else {
260                sb.append("No host disabled.");
261                sb.append("<br />\n");
262            }
263        }
264
265        if (configTplBuilder.titlePlace != null) {
266            configTplBuilder.titlePlace.setText("H3 remote access config");
267        }
268
269        if (configTplBuilder.headingPlace != null) {
270            configTplBuilder.headingPlace.setText("H3 remote access config");
271        }
272
273        if (configTplBuilder.enabledhostsPlace != null) {
274            configTplBuilder.enabledhostsPlace.setText(enabledhostsSb.toString());
275        }
276
277        if (configTplBuilder.contentPlace != null) {
278            configTplBuilder.contentPlace.setText(sb.toString());
279        }
280
281        if (configTplBuilder.versionPlace != null) {
282            configTplBuilder.versionPlace.setText(Constants.getVersionString());
283        }
284
285        if (configTplBuilder.environmentPlace != null) {
286            configTplBuilder.environmentPlace.setText(Settings.get(CommonSettings.ENVIRONMENT_NAME));
287        }
288
289        configTplBuilder.write(out);
290
291        out.flush();
292        out.close();
293    }
294
295}