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(" "); 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(" "); 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}