Author: ssmiweve Date: 2008-04-16 19:10:03 +0200 (Wed, 16 Apr 2008) New Revision: 6474
Modified: trunk/ trunk/core-api/src/main/java/no/sesat/search/run/RunningQueryImpl.java trunk/core-api/src/main/java/no/sesat/search/view/velocity/VelocityEngineFactory.java trunk/data-model-api/src/main/java/no/sesat/search/datamodel/DataModelFactory.java trunk/generic.sesam/pom.xml trunk/generic.sesam/search-command-control/fast/src/main/java/no/sesat/search/mode/command/NewsAggregatorSearchCommand.java trunk/generic.sesam/search-command-control/pom.xml trunk/generic.sesam/war/src/main/templates/VM_sesat_library.vm trunk/httpclient-api/src/main/java/no/sesat/search/http/HTTPClient.java trunk/pom.xml trunk/site-spi/src/main/java/no/sesat/search/site/Site.java trunk/site-spi/src/main/java/no/sesat/search/site/config/SiteConfiguration.java trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java trunk/war/src/main/webapp/WEB-INF/urlrewrite.xml Log: Merged revisions 6390-6473 via svnmerge from http://sesat.no/svn/sesat-kernel/branches/2.17 ................ r6392 | ssmiweve | 2008-04-10 11:21:04 +0200 (Thu, 10 Apr 2008) | 17 lines Merged revisions 6338-6391 via svnmerge from http://sesat.no/svn/sesat-kernel/branches/2.16 ........ r6344 | ssmiweve | 2008-04-03 21:44:11 +0200 (Thu, 03 Apr 2008) | 2 lines http://sesat.no/svn/sesat-kernel ........ r6378 | ssmiweve | 2008-04-07 12:14:14 +0200 (Mon, 07 Apr 2008) | 2 lines mojo: jump forward a version to reap some bugfixes ........ r6391 | ssmiweve | 2008-04-10 10:47:58 +0200 (Thu, 10 Apr 2008) | 1 line OPS-178 Prepare Gamma for secondary production use ........ ................ r6393 | sshafroi | 2008-04-11 09:58:10 +0200 (Fri, 11 Apr 2008) | 1 line Updateing link ................ r6394 | ssmiweve | 2008-04-11 12:01:52 +0200 (Fri, 11 Apr 2008) | 1 line SEARCH-4481 - Personberikelse ved null treff i bedrift har forsvunnet ................ r6395 | ssmiweve | 2008-04-11 15:10:15 +0200 (Fri, 11 Apr 2008) | 1 line SEARCH-4600 - sesam.no/favicon.ico leads to a regular search for "favicon.ico" ................ r6396 | ssmiweve | 2008-04-11 17:49:41 +0200 (Fri, 11 Apr 2008) | 1 line SEARCH-3509 - ?\195?\152ke ytelsen p?\195?\165 forsiden av nyhetss?\195?\184k ................ r6397 | sshafroi | 2008-04-14 09:01:17 +0200 (Mon, 14 Apr 2008) | 1 line build ................ r6445 | ssmiweve | 2008-04-15 14:31:19 +0200 (Tue, 15 Apr 2008) | 1 line better exception handling related to work going on in OPS-209 ................ r6446 | ssmiweve | 2008-04-15 14:36:29 +0200 (Tue, 15 Apr 2008) | 13 lines Merged revisions 6392-6445 via svnmerge from http://sesat.no/svn/sesat-kernel/branches/2.16 ........ r6417 | ssmiweve | 2008-04-14 22:21:33 +0200 (Mon, 14 Apr 2008) | 2 lines SEARCH-4613 - generic.sesam.no configuration files are loaded through apache ........ r6440 | ssmiweve | 2008-04-15 13:42:19 +0200 (Tue, 15 Apr 2008) | 1 line SEARCH-4613 - generic.sesam.no configuration files are loaded through apache ........ ................ r6447 | ssmiweve | 2008-04-15 16:16:21 +0200 (Tue, 15 Apr 2008) | 1 line SEARCH-4620 - Fjerne un?\195?\184dige s?\195?\184k i XML- og RSS-interfacene v?\195?\165re (spesielt bildes?\195?\184ket som koster penger) ................ r6465 | ssmiweve | 2008-04-16 11:52:22 +0200 (Wed, 16 Apr 2008) | 2 lines SEARCH-4613 - generic.sesam.no configuration files are loaded through apache ................ r6466 | ssmiweve | 2008-04-16 11:53:08 +0200 (Wed, 16 Apr 2008) | 9 lines Merged revisions 6446-6465 via svnmerge from http://sesat.no/svn/sesat-kernel/branches/2.16 ........ r6464 | ssmiweve | 2008-04-16 11:07:07 +0200 (Wed, 16 Apr 2008) | 1 line SEARCH-4613 - generic.sesam.no configuration files are loaded through apache ........ ................ r6473 | ssmiweve | 2008-04-16 15:56:22 +0200 (Wed, 16 Apr 2008) | 1 line javadoc fix ................ Property changes on: trunk ___________________________________________________________________ Name: svnmerge-integrated - /branches/2.10:1-4690,4692-4745 /branches/2.11:1-4933 /branches/2.12:1-5051,5053-5106 /branches/2.13:1-5378 /branches/2.14:1-5508 /branches/2.15:1-5995 /branches/2.16:1-6337 /branches/2.17:1-6389 /branches/2.6:1-3877 /branches/2.7:1-4160 /branches/2.8:1-4446 /branches/2.9:1-4626 /branches/MAP_SEARCHv2:1-4544 + /branches/2.10:1-4690,4692-4745 /branches/2.11:1-4933 /branches/2.12:1-5051,5053-5106 /branches/2.13:1-5378 /branches/2.14:1-5508 /branches/2.15:1-5995 /branches/2.16:1-6465 /branches/2.17:1-6389 /branches/2.6:1-3877 /branches/2.7:1-4160 /branches/2.8:1-4446 /branches/2.9:1-4626 /branches/MAP_SEARCHv2:1-4544 Modified: trunk/core-api/src/main/java/no/sesat/search/run/RunningQueryImpl.java =================================================================== --- trunk/core-api/src/main/java/no/sesat/search/run/RunningQueryImpl.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/core-api/src/main/java/no/sesat/search/run/RunningQueryImpl.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -100,6 +100,8 @@ private static final String PARAM_COMMANDS = "commands"; // TODO generic parameter key to be put into ParameterDataObject private static final String PARAM_WAITFOR = "waitFor"; + // TODO generic parameter key to be put into ParameterDataObject + private static final String PARAM_OUTPUT = "output"; private static final Logger LOG = Logger.getLogger(RunningQueryImpl.class); private static final Logger ANALYSIS_LOG = Logger.getLogger("no.sesat.search.analyzer.Analysis"); @@ -384,8 +386,6 @@ return Collections.unmodifiableMap(hits); } - // Private ------------------------------------------------------- - /** Intentionally overridable. Would be nice if run-transform-spi could have influence on the result here. * * @return collection of SearchConfigurations applicable to this running query. @@ -425,6 +425,8 @@ return performTransformers(applicableSearchConfigurations); } + // Private ------------------------------------------------------- + private boolean useEnrichment( final EnrichmentHint eHint, final SearchConfiguration config, @@ -619,10 +621,9 @@ } } - // Inner classes ------------------------------------------------- private boolean isRss() { - final StringDataObject outputParam = datamodel.getParameters().getValue(PARAM_LAYOUT); + final StringDataObject outputParam = datamodel.getParameters().getValue(PARAM_OUTPUT); return null != outputParam && "rss".equals(outputParam.getString()); } Modified: trunk/core-api/src/main/java/no/sesat/search/view/velocity/VelocityEngineFactory.java =================================================================== --- trunk/core-api/src/main/java/no/sesat/search/view/velocity/VelocityEngineFactory.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/core-api/src/main/java/no/sesat/search/view/velocity/VelocityEngineFactory.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -69,7 +69,7 @@ * <b>Developer Aid</b><br/> * Ola-marius extended the engine so to run in debug mode that outlines (& titles) each rendered template. * See - * <a href="https://dev.sesat.no/confluence/display/TECHDEV/Debugging+Velocity+Templates"> + * <a href="http://sesat.no/debugging-velocity-templates.html"> * Debugging Velocity Templates * </a><br/> * Modified: trunk/data-model-api/src/main/java/no/sesat/search/datamodel/DataModelFactory.java =================================================================== --- trunk/data-model-api/src/main/java/no/sesat/search/datamodel/DataModelFactory.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/data-model-api/src/main/java/no/sesat/search/datamodel/DataModelFactory.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -1,4 +1,4 @@ -/* Copyright (2007) Schibsted Søk AS +/* Copyright (2007-2008) Schibsted Søk AS * This file is part of SESAT. * * SESAT is free software: you can redistribute it and/or modify @@ -186,7 +186,13 @@ final String clsName = siteConf.getProperty(DATA_MODEL_FACTORY_IMPL); LOG.info("constructing for " + cxt.getSite() + " instance of " + clsName); - + + if(null == clsName){ + throw new SiteKeyedFactoryInstantiationException( + "Couldn't find " + DATA_MODEL_FACTORY_IMPL + " in " + siteConf.getProperties().toString(), + new NullPointerException()); + } + @SuppressWarnings("unchecked") final Class<DataModelFactory> cls = (Class<DataModelFactory>) Class.forName(clsName); Modified: trunk/generic.sesam/pom.xml =================================================================== --- trunk/generic.sesam/pom.xml 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/generic.sesam/pom.xml 2008-04-16 17:10:03 UTC (rev 6474) @@ -198,7 +198,7 @@ <build><pluginManagement /></build> <properties> - <sesam.site>generic.alpha.test.sesam.no</sesam.site> + <sesam.site>generic.alpha.test.sesam</sesam.site> <!-- QR Servers --> <newsQueryServerURL>http://10.16.195.250:15100</newsQueryServerURL> @@ -242,7 +242,7 @@ <build><pluginManagement /></build> <properties> - <sesam.site>generic.nuclei.test.sesam.no</sesam.site> + <sesam.site>generic.nuclei.test.sesam</sesam.site> <!-- QR Servers --> <newsQueryServerURL>http://10.16.195.250:15100</newsQueryServerURL> @@ -286,7 +286,7 @@ <build><pluginManagement /></build> <properties> - <sesam.site>generic.beta.test.sesam.no</sesam.site> + <sesam.site>generic.beta.test.sesam</sesam.site> <!-- QR Servers --> <newsQueryServerURL>http://10.16.195.250:15100</newsQueryServerURL> @@ -335,7 +335,7 @@ <build><pluginManagement /></build> <properties> - <sesam.site>generic.electron.test.sesam.no</sesam.site> + <sesam.site>generic.electron.test.sesam</sesam.site> <!-- QR Servers --> <newsQueryServerURL>http://10.16.195.250:15100</newsQueryServerURL> @@ -379,7 +379,7 @@ <build><pluginManagement /></build> <properties> - <sesam.site>generic.gamma.test.sesam.no</sesam.site> + <sesam.site>generic.sesam</sesam.site> <!-- QR Servers --> <newsQueryServerURL>http://10.16.195.250:15100</newsQueryServerURL> @@ -425,7 +425,7 @@ <build><pluginManagement /></build> <properties> - <sesam.site>generic.sesam.no</sesam.site> + <sesam.site>generic.sesam</sesam.site> <!-- QR Servers --> <newsQueryServerURL>http://10.16.195.250:15100</newsQueryServerURL> Modified: trunk/generic.sesam/search-command-control/fast/src/main/java/no/sesat/search/mode/command/NewsAggregatorSearchCommand.java =================================================================== --- trunk/generic.sesam/search-command-control/fast/src/main/java/no/sesat/search/mode/command/NewsAggregatorSearchCommand.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/generic.sesam/search-command-control/fast/src/main/java/no/sesat/search/mode/command/NewsAggregatorSearchCommand.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -33,6 +33,9 @@ import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import com.opensymphony.oscache.base.NeedsRefreshException; +import com.opensymphony.oscache.general.GeneralCacheAdministrator; + import java.io.IOException; import java.net.URL; import java.text.ParseException; @@ -64,18 +67,24 @@ super(cxt); } + + @Override public ResultList<? extends ResultItem> execute() { final NewsAggregatorCommandConfig config = getSearchConfiguration(); final StringDataObject clusterId = datamodel.getParameters().getValue(PARAM_CLUSTER_ID); final String xmlUrl = getXmlUrlString(datamodel, config); + LOG.debug("Loading xml file at: " + xmlUrl); + ResultList<? extends ResultItem> searchResult; if (clusterId == null) { - return getPageResult(config, xmlUrl); + searchResult = getPageResult(config, xmlUrl); } else { - return getClusterResult(config, clusterId, xmlUrl); + searchResult = getClusterResult(config, clusterId, xmlUrl); } + LOG.debug("Done (+Tried loading xml file at: " + xmlUrl + ")"); + return searchResult; } - + private String getXmlUrlString(final DataModel dataModel, final NewsAggregatorCommandConfig config) { String geographic = "main"; String category = "main"; @@ -209,12 +218,68 @@ private static final String ATTRIBUTE_CLUSTER_COUNT = "clusters"; private static final String ELEMENT_ENTRY = "entry"; - private Document getDocument(String urlString) throws IOException, SAXException { + private static final GeneralCacheAdministrator CACHE = new GeneralCacheAdministrator(); + private static final int REFRESH_PERIOD = 60; // one minute + private static final int CACHE_CAPACITY = 64; + + private static final Logger LOG = Logger.getLogger(NewsAggregatorXmlParser.class); + + // Static -------------------------------------------------------- + + static{ + CACHE.setCacheCapacity(CACHE_CAPACITY); + } + + /** + * Loads an XML document from a URL i.e. file:// or http:// + * + * @param xmlUrl the url to the xml + * @return the parsed XML as an org.w3c.dom.Document object + * @throws org.xml.sax.SAXException if the underlying sax parser throws an exception + * @throws java.io.IOException if the file could not be read for some reason + */ + private Document getDocumentFromUrl(String urlString) throws IOException, SAXException { + final URL url = new URL(urlString); final HTTPClient httpClient = HTTPClient.instance(url); return httpClient.getXmlDocument(url.getPath()); } + + /** + * Loads an XML document from a URL i.e. file:// or http:// or cache based on a cache timeout + * Gets from URL and stores the result in the cache + * if a NeedsRefreshException is thrown by the cache + * Adapted from TvWaitSearchCommand + * + * @param xmlUrl the url to the xml + * @return the parsed XML as an org.w3c.dom.Document object + * @throws org.xml.sax.SAXException if the underlying sax parser throws an exception + * @throws java.io.IOException if the file could not be read for some reason + */ + private final Document getDocumentFromCache(final String urlString) throws IOException, SAXException { + Document doc; + try { + doc = (Document) CACHE.getFromCache(urlString, REFRESH_PERIOD); + LOG.debug("Got doc from cache for " + urlString); + } catch (NeedsRefreshException e) { + + boolean updatedCache = false; + try{ + doc = getDocumentFromUrl(urlString); + CACHE.putInCache(urlString, doc); + LOG.debug("Got doc from url and added to cache for " + urlString); + updatedCache = true; + }finally{ + if(!updatedCache){ + // prevents a deadlock in CACHE! + CACHE.cancelUpdate(urlString); + } + } + } + return doc; + } + /** * Parses a specific identified cluster * @@ -237,7 +302,7 @@ LOG.debug("Parsing cluster: " + clusterId); // following will either throw a ClassCastException or NPE final FastSearchResult<ResultItem> searchResult = new FastSearchResult<ResultItem>(); - final Document doc = getDocument(xmlUrl); + final Document doc = getDocumentFromCache(xmlUrl); final Element root = doc.getDocumentElement(); List<Element> clusters = getDirectChildren(root, ELEMENT_CLUSTER); for (Element cluster : clusters) { @@ -265,9 +330,10 @@ final NewsAggregatorCommandConfig config, final int offset, final String xmlUrl) throws IOException, SAXException { + // following will throw a ClassCastException or NPE final FastSearchResult<ResultItem> searchResult = new FastSearchResult<ResultItem>(); - final Document doc = getDocument(xmlUrl); + final Document doc = getDocumentFromCache(xmlUrl); final Element root = doc.getDocumentElement(); handleClusters(config, offset, getDirectChildren(root, ELEMENT_CLUSTER), searchResult); @@ -325,7 +391,7 @@ final List<Element> clusters, final ResultList<ResultItem> searchResult) { - int maxOffset = offset + config.getResultsToReturn(); + final int maxOffset = offset + config.getResultsToReturn(); for (int i = offset; i < clusters.size() && i < maxOffset; i++) { Element cluster = clusters.get(i); handleCluster(config, cluster, searchResult); @@ -431,6 +497,7 @@ final NewsAggregatorCommandConfig config, final ResultList<ResultItem> srcResult, final ResultList<ResultItem> targetResult) { + addResult(config, srcResult, targetResult, null, false); } Modified: trunk/generic.sesam/search-command-control/pom.xml =================================================================== --- trunk/generic.sesam/search-command-control/pom.xml 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/generic.sesam/search-command-control/pom.xml 2008-04-16 17:10:03 UTC (rev 6474) @@ -11,6 +11,13 @@ <packaging>pom</packaging> <description>Generic Search Commands</description> + + <dependencies> + <dependency> + <groupId>opensymphony</groupId> + <artifactId>oscache</artifactId> + </dependency> + </dependencies> <modules> <module>default</module> Modified: trunk/generic.sesam/war/src/main/templates/VM_sesat_library.vm =================================================================== --- trunk/generic.sesam/war/src/main/templates/VM_sesat_library.vm 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/generic.sesam/war/src/main/templates/VM_sesat_library.vm 2008-04-16 17:10:03 UTC (rev 6474) @@ -1,9 +1,14 @@ #macro(searchTabInclude $includeName) + ## This is a copy of SearchTabIncludeTag.java. TODO would be nice to merge them both into one. #if($includeName && $layout) #set ($includeValue = "$!layout.getInclude($includeName)") #if($includeValue && $includeValue.trim().length() > 0) <!-- $includeName --> - #parse("$datamodel.site.site.getTemplateDir()/fragments/layout/${includeValue}.vm") + #if( $includeValue.startsWith("/") ) + #parse("$datamodel.site.site.getTemplateDir()${includeValue}.vm") + #else + #parse("$datamodel.site.site.getTemplateDir()/fragments/layout/${includeValue}.vm") + #end #else <!-- $includeName not found --> #end Modified: trunk/httpclient-api/src/main/java/no/sesat/search/http/HTTPClient.java =================================================================== --- trunk/httpclient-api/src/main/java/no/sesat/search/http/HTTPClient.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/httpclient-api/src/main/java/no/sesat/search/http/HTTPClient.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -109,7 +109,7 @@ * * @param host the physical host to use. * @param port the port to use. - * @param hostHeader virtual host to use. + * @param physicalHost virtual host to use. * * @return a client. */ Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/pom.xml 2008-04-16 17:10:03 UTC (rev 6474) @@ -251,7 +251,7 @@ <id>alpha</id> <activation /> <properties> - <sesam.site.generic>generic.alpha.test.sesam.no</sesam.site.generic> + <sesam.site.generic>generic.alpha.test.sesam</sesam.site.generic> <sesam.site.default>${sesam.site.generic}</sesam.site.default> <serverDeployLocation>scpexe://sch-login01.osl.basefarm.net/www/schibstedsok/alpha.test.sesam.no</serverDeployLocation> </properties> @@ -269,7 +269,7 @@ <id>nuclei</id> <activation /> <properties> - <sesam.site.generic>generic.nuclei.test.sesam.no</sesam.site.generic> + <sesam.site.generic>generic.nuclei.test.sesam</sesam.site.generic> <sesam.site.default>${sesam.site.generic}</sesam.site.default> <serverDeployLocation>scpexe://sch-login01.osl.basefarm.net/www/schibstedsok/nuclei.test.sesam.no</serverDeployLocation> </properties> @@ -287,7 +287,7 @@ <id>beta</id> <activation /> <properties> - <sesam.site.generic>generic.beta.test.sesam.no</sesam.site.generic> + <sesam.site.generic>generic.beta.test.sesam</sesam.site.generic> <sesam.site.default>${sesam.site.generic}</sesam.site.default> <serverDeployLocation>scpexe://sch-login01.osl.basefarm.net/www/schibstedsok/beta.test.sesam.no</serverDeployLocation> </properties> @@ -305,7 +305,7 @@ <id>electron</id> <activation /> <properties> - <sesam.site.generic>generic.electron.test.sesam.no</sesam.site.generic> + <sesam.site.generic>generic.electron.test.sesam</sesam.site.generic> <sesam.site.default>${sesam.site.generic}</sesam.site.default> <serverDeployLocation>scpexe://sch-login01.osl.basefarm.net/www/schibstedsok/electron.test.sesam.no</serverDeployLocation> </properties> @@ -323,8 +323,9 @@ <id>gamma</id> <activation /> <properties> - <sesam.site.generic>generic.gamma.test.sesam.no</sesam.site.generic> <sesam.site.default>${sesam.site.generic}</sesam.site.default> + <!-- IMPORTANT: production cannot handle writing to sesam.log at a lower threshold --> + <log.level>WARN</log.level> <serverDeployLocation>scpexe://sch-login01.osl.basefarm.net/www/schibstedsok-prod/gamma.test.sesam.no</serverDeployLocation> </properties> <build> Modified: trunk/site-spi/src/main/java/no/sesat/search/site/Site.java =================================================================== --- trunk/site-spi/src/main/java/no/sesat/search/site/Site.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/site-spi/src/main/java/no/sesat/search/site/Site.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -1,4 +1,4 @@ -/* Copyright (2005-2007) Schibsted Søk AS +/* Copyright (2005-2008) Schibsted Søk AS * This file is part of SESAT. * * SESAT is free software: you can redistribute it and/or modify @@ -31,10 +31,16 @@ import java.util.Properties; import java.util.concurrent.locks.ReentrantReadWriteLock; import no.schibstedsok.commons.ioc.BaseContext; +import org.apache.log4j.Level; import org.apache.log4j.Logger; -/** A Site object idenetifies an unique SiteSearch implementation. - * This bean holds nothing more than the name of the virtual host used to access this SiteSearch. +/** A Site object identifies a Skin + Locale pairing. + * + * This bean holds nothing more than the name of the virtual host (siteName) and locale used to access this Skin. + * + * It is used as a key to obtain the correct factory instances in the application. + * There is usually only one Skin per siteName and it is left up to the skin to handle different locales. + * . * <b>Immutable</b>. * * Does a little bit of niggling wiggling to load the DEFAULT site. See static constructor. @@ -44,12 +50,21 @@ */ public final class Site implements Serializable { - /** Not to be confused with the SiteContext. + /** During construction of any site we must know who the parent site is going to be. + * It will likely be also constructed since leaf sites are those first requested. + * + * The base level sites, locale variants of the DEFAULT site, are expected to have a null parent. + * These DEFAULT sites can just pass in a null context instead of constructing a context that returns a null parent. + * + * Not to be confused with the SiteContext. * This is a Context required for constructing a Site. * While a SiteContext is a context required to use a Site. **/ public interface Context extends BaseContext{ - /** Get the name of the parent site. **/ + /** Get the name of the parent site. + * @param siteContext that can provide the current site the code is within. + * @return the name of the parent site. + */ String getParentSiteName(SiteContext siteContext); } @@ -84,7 +99,7 @@ */ private final String cxtName; /** - * Holds value of property _locale. + * Holds value of property locale. */ private Locale locale; /** @@ -105,16 +120,16 @@ uniqueName = null; parent = null; } - + /** Creates a new instance of Site. * A null Context will result in a parentSiteName == siteName */ private Site(final Context cxt, final String theSiteName, final Locale theLocale) { - - + + try{ INSTANCES_LOCK.writeLock().lock(); - + LOG.info("Site(cxt, " + theSiteName + ", " + theLocale + ')'); assert null != theSiteName; assert null != theLocale; @@ -122,9 +137,7 @@ // siteName must finish with a '\' siteName = ensureTrailingSlash(theSiteName); - cxtName = siteName.indexOf(':') >= 0 - ? siteName.substring(0, siteName.indexOf(':')) + '/' // don't include the port in the cxtName. - : siteName; + cxtName = ensureTrailingSlash(siteName.replaceAll(":.*$", "")); // don't include the port in the cxtName. locale = theLocale; uniqueName = getUniqueName(siteName, locale); @@ -136,18 +149,44 @@ } }; + final String parentSiteName; + if(null != cxt){ + parentSiteName = null != cxt.getParentSiteName(siteContext) + ? ensureTrailingSlash(cxt.getParentSiteName(siteContext)) + : null; + }else{ + parentSiteName = siteName; + } - final String parentSiteName = null != cxt ? cxt.getParentSiteName(siteContext) : siteName; + final String tsParentNameNoPort = null != parentSiteName + ? ensureTrailingSlash(parentSiteName.replaceAll(":.*$", "")) + : null; - parent = null == parentSiteName || ensureTrailingSlash(parentSiteName).equals(siteName) - ? constructingDefault ? null : DEFAULT - : Site.valueOf(cxt, parentSiteName, theLocale); + LOG.debug(siteName + " parent is " + parentSiteName); + if(constructingDefault){ + parent = null; + + }else{ + LOG.debug("Default-check-> " + DEFAULT.getName() + " ?= " + parentSiteName); + + final boolean invalidParent = null == parentSiteName + // also avoid any incest + || siteName.equals(tsParentNameNoPort) + // and detect ahead the link to the grandfather of all "generic.sesam" + || DEFAULT.getName().equals(parentSiteName); + + parent = invalidParent + ? DEFAULT + : Site.valueOf(cxt, parentSiteName, theLocale); + } + assert null != parent || constructingDefault : "Parent must exist for all Sites except the DEFAULT"; - + // register in global pool. + LOG.debug("INSTANCES.put(" + uniqueName + ", this)"); INSTANCES.put(uniqueName, this); - + }finally{ INSTANCES_LOCK.writeLock().unlock(); } @@ -155,8 +194,8 @@ /** the parent to this site. - * returns null if we are the DEFAULT site. - **/ + * @return site null if we are the DEFAULT site. + */ public Site getParent(){ return parent; } @@ -200,25 +239,19 @@ return locale; } - /** [EMAIL PROTECTED] - */ @Override public String toString(){ return uniqueName; } - /** [EMAIL PROTECTED] - */ @Override public boolean equals(final Object obj) { - + return obj instanceof Site ? uniqueName.equals(((Site)obj).uniqueName) : super.equals(obj); } - /** [EMAIL PROTECTED] - */ @Override public int hashCode() { return uniqueName.hashCode(); @@ -227,31 +260,32 @@ /** Get the instance for the given siteName. * The port number will be changed if the server has explicitly assigned one port number to use. * A "www." prefix will be automatically ignored. + * + * TODO refactor to instanceOf(..). it is an instance returned not a primitive. + * * @param cxt the cxt to use during creation. null will prevent constructing a new site. * @param siteName the virtual host name. + * @param locale the locale desired * @return the site bean. */ public static Site valueOf(final Context cxt, final String siteName, final Locale locale) { Site site = null; - - // Tweak the port is SERVER_PORT has been explicitly set. - final String correctedPortSiteName = SERVER_PORT > 0 && siteName.indexOf(':') > 0 - ? siteName.substring(0, siteName.indexOf(':') + 1) + SERVER_PORT - : siteName; // Strip www. from siteName - final String realSiteName = ensureTrailingSlash(correctedPortSiteName.replaceAll("www.", "")); + final String realSiteName = ensureTrailingSlash(siteName.replaceAll("www.", "")); // Look for existing instances + final String uniqueName = getUniqueName(realSiteName,locale); try{ INSTANCES_LOCK.readLock().lock(); - site = INSTANCES.get(getUniqueName(realSiteName,locale)); - + LOG.debug("INSTANCES.get(" + uniqueName + ")"); + site = INSTANCES.get(uniqueName); + }finally{ INSTANCES_LOCK.readLock().unlock(); } - + // construct a new instance if (null == site && null != cxt) { site = new Site(cxt, realSiteName, locale); @@ -263,28 +297,32 @@ final Properties props = new Properties(); final InputStream is = Site.class.getResourceAsStream('/' + CORE_CONF_FILE); - + try { if(null != is){ props.load(is); is.close(); } - + } catch (IOException ex) { - LOG.fatal(FATAL_CANT_FIND_DEFAULT_SITE, ex); + LOG.fatal(FATAL_CANT_FIND_DEFAULT_SITE, ex); } + + final Level oLevel = LOG.getLevel(); + LOG.setLevel(Level.ALL); final String defaultSiteName = props.getProperty(DEFAULT_SITE_KEY, System.getProperty(DEFAULT_SITE_KEY)); LOG.info("defaultSiteName: " + defaultSiteName); - - final String defaultSiteLocaleName + + final String defaultSiteLocaleName = props.getProperty(DEFAULT_SITE_LOCALE_KEY, System.getProperty(DEFAULT_SITE_LOCALE_KEY)); LOG.info("defaultSiteLocaleName: " + defaultSiteLocaleName); - - final String defaultSitePort + + final String defaultSitePort = props.getProperty(DEFAULT_SERVER_PORT_KEY, System.getProperty(DEFAULT_SERVER_PORT_KEY)); LOG.info("defaultSitePort: " + defaultSitePort); + LOG.setLevel(oLevel); SERVER_PORT = Integer.parseInt(defaultSitePort); @@ -307,14 +345,20 @@ /** the server's actual port. **/ public static final int SERVER_PORT; - /** TODO comment me. **/ + /** Get a uniqueName given a pair of siteName and locale. + * Used internally and before construction of any new Site. + * + * @param siteName + * @param locale + * @return + */ public static String getUniqueName(final String siteName, final Locale locale) { - + return siteName + '[' + locale.getDisplayName() + ']'; } private static String ensureTrailingSlash(final String theSiteName) { - + return theSiteName.endsWith("/") ? theSiteName : theSiteName + '/'; Modified: trunk/site-spi/src/main/java/no/sesat/search/site/config/SiteConfiguration.java =================================================================== --- trunk/site-spi/src/main/java/no/sesat/search/site/config/SiteConfiguration.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/site-spi/src/main/java/no/sesat/search/site/config/SiteConfiguration.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -90,6 +90,11 @@ cxt.newPropertiesLoader(cxt, Site.CONFIGURATION_FILE, properties).abut(); INSTANCES.put(cxt.getSite(), this); + + }catch(ResourceLoadException rle){ + LOG.fatal("BROKEN SITE HIERARCHY." + rle.getMessage()); + throw new VirtualMachineError(rle.getMessage()){}; + } finally { INSTANCES_LOCK.writeLock().unlock(); } Modified: trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java =================================================================== --- trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java 2008-04-16 17:10:03 UTC (rev 6474) @@ -35,6 +35,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import javax.enterprise.deploy.model.J2eeApplicationObject; +import javax.enterprise.deploy.model.J2eeApplicationObject; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -53,6 +55,7 @@ import no.sesat.search.site.config.UrlResourceLoader; import no.sesat.search.site.Site; import no.sesat.search.datamodel.DataModel; +import no.sesat.search.site.config.ResourceLoadException; import no.sesat.search.view.FindResource; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.time.StopWatch; @@ -105,8 +108,14 @@ final Properties props = new Properties(); final PropertiesLoader loader = UrlResourceLoader.newPropertiesLoader(siteContext, Site.CONFIGURATION_FILE, props); - loader.abut(); - return props.getProperty(Site.PARENT_SITE_KEY); + try{ + loader.abut(); + return props.getProperty(Site.PARENT_SITE_KEY); + + }catch(ResourceLoadException rle){ + LOG.fatal("BROKEN SITE HIERARCHY." + rle.getMessage()); + throw new VirtualMachineError(rle.getMessage()){}; + } } }; @@ -304,12 +313,16 @@ // 2) "UseCanonicalName Off" to assign ServerName from client's request. final String vhost = getServerName(servletRequest); + // Tweak the port if SERVER_PORT has been explicitly set. (We may have gone through Apache or Cisco LB). + final String correctedVhost = Site.SERVER_PORT > 0 && vhost.indexOf(':') > 0 + ? vhost.substring(0, vhost.indexOf(':') + 1) + Site.SERVER_PORT + : vhost; - LOG.trace(DEBUG_REQUESTED_VHOST + vhost); + LOG.trace(DEBUG_REQUESTED_VHOST + correctedVhost); // Construct the site object off the browser's locale, even if it won't finally be used. final Locale locale = servletRequest.getLocale(); - final Site result = Site.valueOf(SITE_CONTEXT, vhost, locale); + final Site result = Site.valueOf(SITE_CONTEXT, correctedVhost, locale); final SiteConfiguration.Context siteConfCxt = new SiteConfiguration.Context(){ public PropertiesLoader newPropertiesLoader( final SiteContext siteCxt, @@ -344,16 +357,16 @@ case 3: LOG.trace(result+INFO_USING_DEFAULT_LOCALE + prefLocale[0] + '_' + prefLocale[1] + '_' + prefLocale[2]); - return Site.valueOf(SITE_CONTEXT, vhost, new Locale(prefLocale[0], prefLocale[1], prefLocale[2])); + return Site.valueOf(SITE_CONTEXT, correctedVhost, new Locale(prefLocale[0], prefLocale[1], prefLocale[2])); case 2: LOG.trace(result+INFO_USING_DEFAULT_LOCALE + prefLocale[0] + '_' + prefLocale[1]); - return Site.valueOf(SITE_CONTEXT, vhost, new Locale(prefLocale[0], prefLocale[1])); + return Site.valueOf(SITE_CONTEXT, correctedVhost, new Locale(prefLocale[0], prefLocale[1])); case 1: default: LOG.trace(result+INFO_USING_DEFAULT_LOCALE + prefLocale[0]); - return Site.valueOf(SITE_CONTEXT, vhost, new Locale(prefLocale[0])); + return Site.valueOf(SITE_CONTEXT, correctedVhost, new Locale(prefLocale[0])); } } Modified: trunk/war/src/main/webapp/WEB-INF/urlrewrite.xml =================================================================== --- trunk/war/src/main/webapp/WEB-INF/urlrewrite.xml 2008-04-16 13:56:22 UTC (rev 6473) +++ trunk/war/src/main/webapp/WEB-INF/urlrewrite.xml 2008-04-16 17:10:03 UTC (rev 6474) @@ -30,6 +30,7 @@ <rule><from>^/index.jsp$</from><to>/</to></rule> <rule><from>^/$</from><to>/search/?</to></rule> <rule><from>^/robots.txt$</from><to>/robots.jsp</to></rule> + <rule><from>^/favicon.ico$</from><to type="permanent-redirect">/images/favicon.ico</to></rule> <rule><from>^/psearch/(.*)$</from><to>/search/$1</to></rule> <!-- makes it easy to upload google verification html files --> _______________________________________________ Kernel-commits mailing list [email protected] http://sesat.no/mailman/listinfo/kernel-commits
