Changeset 7771

Show
Ignore:
Timestamp:
07/07/09 12:18:29 (13 months ago)
Author:
dragisak
Message:

Remove the need to build journal template jar files. Instead, templates are placed under directory specified in ambra.virtualJournals.templateDir configuration paramater.

  • Each journal is placed under journals/journal-name
  • Journal configuration file is placed in journals/journal-name/configuration/journal.xml
  • Freemarker templates and static resources (images, css, javascript, etc) are placed under journals/journal-name/webapp

Deployment can be done directly from version control system if ambra.virtualJournals.templateDir is set to point to source head directory.

Addresses #919

Location:
head/ambra
Files:
4 added
15 modified
1 moved

Legend:

Unmodified
Added
Removed
  • head/ambra/libs/conf-helper/src/main/java/org/topazproject/ambra/configuration/ConfigurationStore.java

    r7756 r7771  
    2222import java.net.MalformedURLException; 
    2323import java.util.Enumeration; 
     24import java.util.Collection; 
    2425import java.io.IOException; 
    2526import java.io.FileNotFoundException; 
     27import java.io.File; 
    2628 
    2729import org.apache.commons.configuration.AbstractConfiguration; 
     
    8688 
    8789  /** 
    88    * Name of resource(s) that contain defaults in a given library or web application.<p> 
    89    * 
    90    * Note that multiple copies of these may exist in the same classpath. ALL are read 
    91    * and added to the configuration. It is assumed that developers use appropriate 
    92    * namespaces to avoid collisions.<p> 
    93    * 
    94    * Also note that this does not begin with a / as ClassLoader.getResources() does 
    95    * not want this to begin with a /. 
    96    */ 
     90   * <p>Name of resource(s) that contain defaults in a given journal</p> 
     91   * 
     92   * <p>There is one per journal.</p> 
     93   */ 
     94  public static final String JOURNAL_DIRECTORY = "/configuration/journal.xml"; 
    9795  public static final String DEFAULTS_RESOURCE = "ambra/configuration/defaults.xml"; 
    9896 
     
    104102   */ 
    105103  public static final String GLOBAL_DEFAULTS_RESOURCE = "/ambra/configuration/global-defaults.xml"; 
     104 
     105  /** 
     106   * Location of journal templates 
     107   */ 
     108  public static final String JOURNAL_TEMPLATE_DIR = "ambra.virtualJournals.templateDir"; 
     109  private static final String JOURNALS = "ambra.virtualJournals.journals"; 
    106110 
    107111  /** 
     
    179183    } 
    180184 
    181     // Add defaults.xml found in classpath 
    182185    CombinedConfiguration defaults = new CombinedConfiguration(new UnionCombiner()); 
     186    // Add defaults.xml from classpath 
    183187    addResources(defaults, DEFAULTS_RESOURCE); 
     188    // Add journal.xml from journals/journal-name/configuration/journal.xml 
     189    addJournalResources(root, defaults, JOURNAL_DIRECTORY); 
    184190    root.addConfiguration(defaults); 
    185191 
     
    256262    } 
    257263  } 
     264 
     265  public static void addJournalResources(CombinedConfiguration root, CombinedConfiguration defaults, String path) 
     266      throws ConfigurationException { 
     267 
     268     Collection<String> journals = root.getList(JOURNALS); 
     269     String journalTemplatePath = root.getString(ConfigurationStore.JOURNAL_TEMPLATE_DIR, "/"); 
     270 
     271    for (String journal : journals) { 
     272 
     273      String resourcePath = journalTemplatePath 
     274          + (journalTemplatePath.endsWith("/") ? "journals/" : "/journals/") 
     275          + journal 
     276          + path; 
     277 
     278      File defaultsXmlFile = new File(resourcePath); 
     279      if (defaultsXmlFile.isFile() && defaultsXmlFile.canRead()) { 
     280        defaults.addConfiguration(new XMLConfiguration(defaultsXmlFile)); 
     281        log.info("Added resource '" + resourcePath + "' to configuration"); 
     282      } 
     283    } 
     284  } 
    258285} 
  • head/ambra/libs/conf-helper/src/test/java/org/topazproject/ambra/configuration/ConfigurationTest.java

    r7193 r7771  
    22 * $Id$ 
    33 * 
    4  * Copyright (c) 2006-2008 by Topaz, Inc. 
     4 * Copyright (c) 2006-2009 by Topaz, Inc. 
    55 * http://topazproject.org 
    66 * 
     
    2020 
    2121import java.util.List; 
     22import java.net.URL; 
    2223 
    2324import org.apache.commons.configuration.CombinedConfiguration; 
     
    3334  protected void setUp() throws ConfigurationException { 
    3435    ConfigurationStore store = ConfigurationStore.getInstance(); 
    35     store.loadConfiguration(null); 
     36    ClassLoader loader = getClass().getClassLoader(); 
     37    System.setProperty("ambra.virtualJournals.templateDir", loader.getResource(".").getFile()); 
     38    store.loadConfiguration(loader.getResource("ambra/configuration/defaults-dev.xml")); 
    3639    conf = store.getConfiguration(); 
    3740    /* 
     
    5659 
    5760  public void testDefaultsOverrideGlobal() { 
    58     assertEquals("defaults override", "override", conf.getString("conf.def")); 
    59   } 
    60  
    61   private void checkExpTest(List l) { 
    62     assertNotNull(l); 
    63     assertEquals(3, l.size()); 
    64     assertEquals("http://test1:8080/", l.get(0)); 
    65     assertEquals("http://test2:8080/", l.get(1)); 
    66     assertEquals("http://test1:8080/", l.get(2)); 
     61    assertEquals("defaults override", "override-dev", conf.getString("conf.def")); 
    6762  } 
    6863 
     
    9489    checkExpTest(conf.getList("overrides.item")); 
    9590  } 
     91 
     92  private void checkExpTest(List l) { 
     93    assertNotNull(l); 
     94    assertEquals(3, l.size()); 
     95    assertEquals("http://test1:8080/", l.get(0)); 
     96    assertEquals("http://test2:8080/", l.get(1)); 
     97    assertEquals("http://test1:8080/", l.get(2)); 
     98  } 
     99 
     100 
    96101} 
  • head/ambra/libs/conf-helper/src/test/resources/ambra/configuration/defaults-dev.xml

    r6233 r7771  
    44  $Id$ 
    55   
    6   Copyright (c) 2006-2008 by Topaz, Inc. 
     6  Copyright (c) 2006-2009 by Topaz, Inc. 
    77  http://topazproject.org 
    88   
     
    2323    <def>override-dev</def> 
    2424  </conf> 
     25  <ambra> 
     26    <virtualJournals> 
     27      <journals>test</journals> 
     28    </virtualJournals> 
     29  </ambra> 
    2530</config> 
  • head/ambra/libs/conf-helper/src/test/resources/journals/test/configuration/journal.xml

    r6233 r7771  
    11<?xml version="1.0" encoding="UTF-8" ?> 
    22<!-- 
    3   $HeadURL::                                                                            $ 
    4   $Id$ 
     3  $HeadURL:: http://svn.topazproject.org/svn/head/ambra/libs/conf-helper/src/test/resou#$ 
     4  $Id: defaults.xml 6233 2008-07-28 17:18:37Z pradeep $ 
    55   
    66  Copyright (c) 2006-2008 by Topaz, Inc. 
  • head/ambra/webapp/pom.xml

    r7764 r7771  
    1515 
    1616  <dependencies> 
    17  
    18     <!--dependency> 
    19       <groupId>org.topazproject</groupId> 
    20       <artifactId>journal-ambraJournal</artifactId> 
    21       <version>${pom.version}</version> 
    22     </dependency> 
    23     <dependency> 
    24       <groupId>org.topazproject</groupId> 
    25       <artifactId>journal-overlay</artifactId> 
    26       <version>${pom.version}</version> 
    27     </dependency--> 
    28  
    29  
    30     <dependency> 
    31       <groupId>org.plos</groupId> 
    32       <artifactId>PLoSDefault</artifactId> 
    33       <version>0.9.3.2-SNAPSHOT</version> 
    34     </dependency> 
    35     <dependency> 
    36       <groupId>org.plos</groupId> 
    37       <artifactId>PLoSBiology</artifactId> 
    38       <version>0.9.3.2-SNAPSHOT</version> 
    39     </dependency> 
    40     <dependency> 
    41       <groupId>org.plos</groupId> 
    42       <artifactId>PLoSClinicalTrials</artifactId> 
    43       <version>0.9.3.2-SNAPSHOT</version> 
    44     </dependency> 
    45     <dependency> 
    46       <groupId>org.plos</groupId> 
    47       <artifactId>PLoSCompBiol</artifactId> 
    48       <version>0.9.3.2-SNAPSHOT</version> 
    49     </dependency> 
    50     <dependency> 
    51       <groupId>org.plos</groupId> 
    52       <artifactId>PLoSGenetics</artifactId> 
    53       <version>0.9.3.2-SNAPSHOT</version> 
    54     </dependency> 
    55     <dependency> 
    56       <groupId>org.plos</groupId> 
    57       <artifactId>PLoSMedicine</artifactId> 
    58       <version>0.9.3.2-SNAPSHOT</version> 
    59     </dependency> 
    60     <dependency> 
    61       <groupId>org.plos</groupId> 
    62       <artifactId>PLoSNTD</artifactId> 
    63       <version>0.9.3.2-SNAPSHOT</version> 
    64     </dependency> 
    65     <dependency> 
    66       <groupId>org.plos</groupId> 
    67       <artifactId>PLoSONE</artifactId> 
    68       <version>0.9.3.2-SNAPSHOT</version> 
    69     </dependency> 
    70     <dependency> 
    71       <groupId>org.plos</groupId> 
    72       <artifactId>PLoSPathogens</artifactId> 
    73       <version>0.9.3.2-SNAPSHOT</version> 
    74     </dependency> 
    7517 
    7618    <dependency> 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/struts2/AmbraFreemarkerConfig.java

    r7764 r7771  
    6565  private String changeEmailURL; 
    6666  private String defaultJournalName; 
    67   private String defaultJournalMappingPrefix; 
    6867  private String orgName; 
    6968  private String feedbackEmail; 
     
    9392    almHost = configuration.getString("ambra.services.alm.url"); 
    9493    defaultJournalName = configuration.getString(DEFAULT_JOURNAL_NAME_CONFIG_KEY); 
    95     defaultJournalMappingPrefix = configuration.getString(VirtualJournalContextFilter.CONF_VIRTUALJOURNALS + 
    96         "." + defaultJournalName + ".mappingPrefix"); 
    9794    journals = new HashMap<String, JournalConfig>(); 
    9895    orgName = configuration.getString("ambra.platform.name"); 
     
    10081005  } 
    10091006 
    1010   public String getDefaultJournalMappingPrefix() { 
    1011     return defaultJournalMappingPrefix; 
     1007  public String getDefaultJournalName() { 
     1008    return defaultJournalName; 
    10121009  } 
    10131010} 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/struts2/AmbraFreemarkerManager.java

    r7764 r7771  
    2222import java.io.IOException; 
    2323import java.io.Reader; 
     24import java.io.File; 
     25import java.util.StringTokenizer; 
    2426 
    2527import javax.servlet.ServletContext; 
     
    2931import org.apache.struts2.views.freemarker.FreemarkerManager; 
    3032import org.apache.struts2.views.freemarker.ScopesHashModel; 
     33import org.apache.struts2.views.freemarker.StrutsClassTemplateLoader; 
    3134import org.apache.struts2.ServletActionContext; 
     35import org.apache.commons.logging.Log; 
     36import org.apache.commons.logging.LogFactory; 
    3237import org.topazproject.ambra.util.AuthorNameAbbreviationDirective; 
    3338import org.topazproject.ambra.util.ArticleFormattingDirective; 
    3439import org.topazproject.ambra.util.SimpleTextDirective; 
    3540import org.topazproject.ambra.web.VirtualJournalContext; 
     41import org.topazproject.ambra.configuration.ConfigurationStore; 
     42import org.springframework.beans.factory.annotation.Required; 
    3643 
    3744import com.opensymphony.xwork2.util.ValueStack; 
     
    3946import freemarker.cache.TemplateLoader; 
    4047import freemarker.cache.StatefulTemplateLoader; 
     48import freemarker.cache.FileTemplateLoader; 
     49import freemarker.cache.MultiTemplateLoader; 
     50import freemarker.cache.WebappTemplateLoader; 
    4151import freemarker.template.TemplateException; 
    4252import freemarker.template.Configuration; 
     
    4959 */ 
    5060public class AmbraFreemarkerManager extends FreemarkerManager { 
    51   private AmbraFreemarkerConfig fmConfig; 
     61 
     62  private static final Log log = LogFactory.getLog(AmbraFreemarkerManager.class); 
     63 
     64  private AmbraFreemarkerConfig freemarkerConfig; 
     65  private org.apache.commons.configuration.Configuration configuration; 
    5266 
    5367  /** 
    5468   * Sets the custom configuration object via Spring injection 
    5569   * 
    56    * @param fmConfig Freemarker configuration 
    5770   */ 
    58   public AmbraFreemarkerManager(AmbraFreemarkerConfig fmConfig) { 
    59     this.fmConfig = fmConfig; 
     71 
     72 
     73 
     74 
     75  public AmbraFreemarkerManager() { 
     76  } 
     77 
     78  @Required 
     79  public void setAmbraFreemarkerConfig(AmbraFreemarkerConfig fmConfig) { 
     80    this.freemarkerConfig = fmConfig; 
     81  } 
     82 
     83  @Required 
     84  public void setAmbraConfiguration( org.apache.commons.configuration.Configuration configuration) { 
     85    this.configuration = configuration; 
    6086  } 
    6187 
     
    6995                                 HttpServletRequest request, HttpServletResponse response) { 
    7096    super.populateContext(model, stack, action, request, response); 
    71     model.put("freemarker_config", fmConfig); 
     97    model.put("freemarker_config", freemarkerConfig); 
    7298  } 
    7399 
    74100  @Override 
    75   protected TemplateLoader getTemplateLoader(ServletContext context) { 
    76     final TemplateLoader s = super.getTemplateLoader(context); 
     101  protected TemplateLoader getTemplateLoader(final ServletContext context) { 
    77102 
    78103    return new StatefulTemplateLoader() { 
     104 
     105      private final TemplateLoader templateLoader; 
     106 
     107      // anonymous initializer 
     108      { 
     109        String journalTemplatePath = configuration.getString(ConfigurationStore.JOURNAL_TEMPLATE_DIR, null); 
     110        FileTemplateLoader templatePathLoader = null; 
     111        try { 
     112          templatePathLoader = new FileTemplateLoader(new File(journalTemplatePath)); 
     113        } catch (IOException e) { 
     114          log.error("Invalid template path " + journalTemplatePath + " in " + ConfigurationStore.JOURNAL_TEMPLATE_DIR); 
     115        } 
     116 
     117        this.templateLoader = templatePathLoader != null ? 
     118            new MultiTemplateLoader(new TemplateLoader[]{ 
     119                templatePathLoader, 
     120                new WebappTemplateLoader(context), 
     121                new StrutsClassTemplateLoader() 
     122            }) 
     123            : new MultiTemplateLoader(new TemplateLoader[]{ 
     124            new WebappTemplateLoader(context), 
     125            new StrutsClassTemplateLoader() 
     126        }); 
     127      } 
     128 
    79129      public void closeTemplateSource(Object source) throws IOException { 
    80         s.closeTemplateSource(source); 
     130        templateLoader.closeTemplateSource(source); 
    81131      } 
    82132 
     
    92142 
    93143        // Second: look into site-specific override templates 
    94         templateSource = getDefaultTemplate(trimmedPath); 
    95         if (templateSource != null) 
    96           return templateSource; 
     144        if (freemarkerConfig.getDefaultJournalName() != null) { 
     145          templateSource = getDefaultTemplate(trimmedPath); 
     146          if (templateSource != null) 
     147            return templateSource; 
     148        } 
    97149 
    98150        // Third: look in the ambra default folders 
    99         templateSource = s.findTemplateSource(trimmedPath); 
     151        templateSource = templateLoader.findTemplateSource(trimmedPath); 
    100152        if (templateSource != null) 
    101153          return templateSource; 
     
    107159         */ 
    108160        if (templatePath.indexOf("ambra-theme") >= 0) 
    109           return s.findTemplateSource(templatePath.replace("ambra-theme", "simple")); 
     161          return templateLoader.findTemplateSource(templatePath.replace("ambra-theme", "simple")); 
    110162        else 
    111163          return null; 
     
    114166 
    115167      private Object getDefaultTemplate(String templatePath) throws IOException { 
    116         String defaultPath = defaultPath(templatePath); 
    117  
    118         return s.findTemplateSource("struts" 
    119             + (defaultPath.startsWith("/") ? "" : "/") 
    120             + defaultPath); 
     168 
     169        return templateLoader.findTemplateSource(defaultPath(templatePath)); 
    121170      } 
    122171 
     
    125174 
    126175        // If path doesn't start with journal append current journal context 
    127         if (!templatePath.startsWith("journals") && !templatePath.startsWith("/journals")) { 
     176        if (templatePath.startsWith("journals") || templatePath.startsWith("/journals")) { 
     177          journalSpecificTemplatePath = addWebappToPath(journalSpecificTemplatePath); 
     178        } else { 
    128179          journalSpecificTemplatePath = journalizePath(journalSpecificTemplatePath); 
    129180        } 
    130181 
    131         return s.findTemplateSource("struts" 
    132             + (journalSpecificTemplatePath.startsWith("/") ? "" : "/") 
    133             + journalSpecificTemplatePath); 
     182        return templateLoader.findTemplateSource(journalSpecificTemplatePath); 
    134183      } 
    135184 
    136185      public long getLastModified(Object source) { 
    137         return s.getLastModified(source); 
     186        return templateLoader.getLastModified(source); 
    138187      } 
    139188 
    140189      public Reader getReader(Object source, String encoding) throws IOException { 
    141         return s.getReader(source, encoding); 
     190        return templateLoader.getReader(source, encoding); 
    142191      } 
    143192 
    144193      public void resetState() { 
    145         if (s instanceof StatefulTemplateLoader) 
    146           ((StatefulTemplateLoader) s).resetState(); 
     194        if (templateLoader instanceof StatefulTemplateLoader) 
     195          ((StatefulTemplateLoader) templateLoader).resetState(); 
    147196      } 
    148197 
     
    150199       * Add journal mapping prefix to template path 
    151200       * @param templatePath Template path 
    152        * @return Template path prefixed with journal mapping prefix 
     201       * @return Template path in form /journals/journalName/webapp/templatePath 
    153202       */ 
    154203      private String journalizePath(String templatePath) { 
     
    161210          return templatePath; 
    162211 
    163         return journalContext.getMappingPrefix() 
    164             + (templatePath.startsWith("/") ? "" : "/") 
    165             + templatePath; 
     212        StringBuilder journalizedPath = new StringBuilder(); 
     213        journalizedPath.append("/journals/") 
     214            .append(journalContext.getJournal()) 
     215            .append((templatePath.startsWith("/") ? "/webapp" : "/webapp/")) 
     216            .append(templatePath); 
     217 
     218        return journalizedPath.toString(); 
     219 
     220      } 
     221 
     222      private String addWebappToPath(String templatePath) { 
     223        StringTokenizer tokenizer = new StringTokenizer(templatePath, "/"); 
     224        StringBuilder stringBuilder = new StringBuilder(); 
     225        boolean addToNext = false; 
     226        while (tokenizer.hasMoreTokens()) { 
     227          String token = tokenizer.nextToken(); 
     228          stringBuilder.append('/').append(token); 
     229          if (addToNext && token.equals("webapp")) 
     230            addToNext = false; 
     231          if (addToNext) { 
     232            stringBuilder.append("/webapp"); 
     233            addToNext = false; 
     234          } else if (token.equals("journals")) 
     235            addToNext = true; 
     236 
     237        } 
     238 
     239        return stringBuilder.toString(); 
    166240 
    167241      } 
     
    169243      private String defaultPath(String templatePath) { 
    170244 
    171         return fmConfig.getDefaultJournalMappingPrefix() 
    172             + (templatePath.startsWith("/") ? "" : "/") 
    173             + templatePath; 
     245        StringBuilder defaultPath = new StringBuilder(); 
     246 
     247        defaultPath.append("/journals/") 
     248            .append(freemarkerConfig.getDefaultJournalName()) 
     249            .append("/webapp") 
     250            .append((templatePath.startsWith("/") ? "" : "/")) 
     251            .append(templatePath); 
     252        return defaultPath.toString(); 
     253 
    174254      } 
    175255    }; 
     
    186266  protected Configuration createConfiguration(ServletContext servletContext) throws TemplateException { 
    187267    Configuration configuration = super.createConfiguration(servletContext); 
     268/* 
     269    configuration.setServletContextForTemplateLoading(servletContext, "/"); 
     270    try { 
     271      configuration.setDirectoryForTemplateLoading(new File("/")); 
     272    } catch (IOException e) { 
     273      throw new TemplateException("Error setting root directory", e, Environment.getCurrentEnvironment()); 
     274    } 
     275*/ 
    188276    configuration.setSharedVariable("abbreviation", new AuthorNameAbbreviationDirective()); 
    189277    configuration.setSharedVariable("articleFormat", new ArticleFormattingDirective()); 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/struts2/AmbraFreemarkerResult.java

    r7197 r7771  
    22 * $Id$ 
    33 * 
    4  * Copyright (c) 2006-2007 by Topaz, Inc. 
     4 * Copyright (c) 2006-2009 by Topaz, Inc. 
    55 * http://topazproject.org 
    66 * 
     
    7979          .getAttribute(VirtualJournalContext.PUB_VIRTUALJOURNAL_CONTEXT); 
    8080        if (virtualJournalContext != null) { 
    81           templateFileName = virtualJournalContext.getMappingPrefix()+templateFile; 
     81          templateFileName = "/journals/" + virtualJournalContext.getJournal() + templateFile; 
    8282          if (log.isDebugEnabled()) { 
    8383            log.debug("Changed "+templateFile+" to "+templateFileName); 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/struts2/AmbraStruts2Dispatcher.java

    r7197 r7771  
    22 * $Id$ 
    33 * 
    4  * Copyright (c) 2006-2007 by Topaz, Inc. 
     4 * Copyright (c) 2006-2009 by Topaz, Inc. 
    55 * http://topazproject.org 
    66 * 
     
    8787   * inherited javadoc 
    8888   */ 
     89  @Override 
    8990  protected Dispatcher createDispatcher(FilterConfig filterConfig) { 
    9091    Map<String, String> params               = new HashMap<String, String>(); 
     
    108109 
    109110    return new Dispatcher(filterConfig.getServletContext(), params); 
    110   } 
     111    } 
    111112 
    112113  /** 
     
    117118   * @return A string array of packages 
    118119   */ 
     120  @Override 
    119121  protected String[] parse(String packages) { 
    120122    pathPrefixes = super.parse(packages); 
    121  
    122123    return pathPrefixes; 
    123124  } 
     
    133134   * @throws IOException If anything goes wrong 
    134135   */ 
     136  @Override 
    135137  protected void findStaticResource(String name, HttpServletRequest request, 
    136138                                    HttpServletResponse response) 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/web/HttpResourceServer.java

    r7198 r7771  
    22 * $Id$ 
    33 * 
    4  * Copyright (c) 2006-2008 by Topaz, Inc. 
     4 * Copyright (c) 2006-2009 by Topaz, Inc. 
    55 * http://topazproject.org 
    66 * 
     
    2424import java.io.PrintWriter; 
    2525import java.io.Reader; 
     26import java.io.File; 
     27import java.io.FileInputStream; 
    2628 
    2729import java.net.URL; 
     
    10791081  } 
    10801082 
     1083  public static class FileResource extends Resource { 
     1084 
     1085    private final File file; 
     1086 
     1087    public FileResource(File file) { 
     1088      super(file.getName(), guessContentType(file.getName()), file.length(), file.lastModified()); 
     1089      this.file = file; 
     1090    } 
     1091 
     1092    public InputStream streamContent() throws IOException { 
     1093      return new FileInputStream(file); 
     1094    } 
     1095 
     1096    public byte[] getContent() { 
     1097      return null; 
     1098    } 
     1099  } 
     1100 
     1101 
    10811102  public static class URLResource extends Resource { 
    10821103    private final URL url; 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/web/VirtualJournalContextFilter.java

    r7767 r7771  
    8989 
    9090    String defaultJournal = configuration.getString(CONF_VIRTUALJOURNALS_DEFAULT); 
    91     String defaultMappingPrefix = getMappingPrefix(defaultJournal); 
    9291 
    9392    // need to do <rule> based processing 
    9493    String journalName = findMatchingVirtualJournal(configuration, (HttpServletRequest) request); 
    95     String mappingPrefix; 
    9694 
    9795    if (journalName != null) { 
    98       mappingPrefix  = getMappingPrefix(journalName); 
    99       if (log.isTraceEnabled()) { 
    100         log.trace("journal from rules: journal = \"" + journalName + "\"" + 
    101             ", mappingPrefix = \"" + mappingPrefix + "\""); 
     96      if (log.isTraceEnabled()) { 
     97        log.trace("journal from rules: journal = \"" + journalName + "\""); 
    10298      } 
    10399    } else { 
     
    105101 
    106102      journalName = defaultJournal; 
    107       mappingPrefix = defaultMappingPrefix; 
    108  
    109       if (log.isTraceEnabled()) { 
    110         log.trace("journal from defaults: journal = \"" + journalName + "\"" + 
    111                   ", mappingPrefix = \"" + mappingPrefix + "\""); 
     103 
     104      if (log.isTraceEnabled()) { 
     105        log.trace("journal from defaults: journal = \"" + journalName + "\""); 
    112106      } 
    113107    } 
     
    116110    if (journalName == null) { 
    117111      journalName = ""; 
    118       mappingPrefix  = ""; 
    119112 
    120113      if (log.isTraceEnabled()) { 
     
    124117 
    125118    if (log.isDebugEnabled()) { 
    126       log.debug("journal = \"" + journalName + "\""  
    127           + ", mappingPrefix = \"" + mappingPrefix + "\" for "  
     119      log.debug("journal = \"" + journalName + "\" for " 
    128120          + ((HttpServletRequest)request).getRequestURL()); 
    129121    } 
     
    133125      new VirtualJournalContext( 
    134126          journalName, 
    135           mappingPrefix, 
    136           defaultMappingPrefix, 
     127          defaultJournal, 
    137128          request.getScheme(), 
    138129          request.getServerPort(), 
     
    156147  } 
    157148 
    158   private String getMappingPrefix(String journalName) { 
    159     return configuration.getString(CONF_VIRTUALJOURNALS + "." + journalName + 
    160                                                   ".mappingPrefix"); 
    161   } 
    162  
    163149  /** 
    164150   * Process all &lt;${journal-name}&gt;&lt;rules&gt;&lt;${http-header-name}&gt;s looking for a match. 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/web/VirtualJournalContext.java

    r7764 r7771  
    5858   */ 
    5959  public VirtualJournalContext(final String journal, 
    60                                final String mappingPrefix, 
    61                                final String defaultMappingPrefix, 
     60                               final String defaultJournal, 
    6261                               final String requestScheme, 
    6362                               final int requestPort, 
     
    6766 
    6867    this.journal           = journal; 
    69     this.mappingPrefix     = mappingPrefix; 
    70     this.defaultMappingPrefix = defaultMappingPrefix; 
    7168    this.requestScheme     = requestScheme; 
    7269    this.requestPort       = requestPort; 
    7370    this.requestServerName = requestServerName; 
    7471    this.requestContext    = requestContext; 
     72    this.mappingPrefix = "journals/" + journal; 
     73    this.defaultMappingPrefix = "journals/" + defaultJournal; 
    7574 
    7675    StringBuilder urlBaseValue = new StringBuilder(); 
     
    238237 
    239238  /** 
    240    * Get the virtual journal mapping prefix. 
    241    * 
    242    * @return Mapping prefix, may be "". 
    243    */ 
    244   public String getMappingPrefix() { 
    245     return mappingPrefix; 
    246   } 
    247  
    248   /** 
    249239   * Get the virtual journal Request scheme. 
    250240   * 
  • head/ambra/webapp/src/main/java/org/topazproject/ambra/web/VirtualJournalMappingFilter.java

    r7764 r7771  
    2020 
    2121import java.io.IOException; 
     22import java.io.File; 
    2223 
    2324import java.net.MalformedURLException; 
     25import java.util.StringTokenizer; 
    2426 
    2527import javax.servlet.Filter; 
     
    3537import org.apache.commons.logging.Log; 
    3638import org.apache.commons.logging.LogFactory; 
     39import org.apache.commons.configuration.Configuration; 
     40import org.topazproject.ambra.configuration.ConfigurationStore; 
    3741 
    3842/** 
     
    4650  private static final Log log            = LogFactory.getLog(VirtualJournalMappingFilter.class); 
    4751  private ServletContext   servletContext = null; 
     52  private Configuration configuration = null; 
    4853 
    4954  /* 
     
    5257  public void init(final FilterConfig filterConfig) throws ServletException { 
    5358    // need ServletContext to get "real" path/file names 
    54     servletContext = filterConfig.getServletContext(); 
     59    this.servletContext = filterConfig.getServletContext(); 
     60    this.configuration = ConfigurationStore.getInstance().getConfiguration(); 
    5561  } 
    5662 
     
    108114      return request; 
    109115 
    110     String mappingPrefix = context.getMappingPrefix(); 
    111  
    112     if ((mappingPrefix == null) || (mappingPrefix.length() == 0)) 
    113       return request; 
    114  
    115116    String cp      = request.getContextPath(); 
    116117    String sp      = request.getServletPath(); 
     
    142143    // strip contextPath ("/ambra-webapp") from resource path 
    143144    String resource = paths[3].substring(paths[0].length()); 
    144     if (resourceExistsInServletContext(resource)) 
    145       return paths; 
    146  
    147     if (resource.startsWith("/journals")) { 
    148       String path = "struts" + resource; 
    149  
    150       if (resourceExistsInClasspath(path)) 
    151         return new String[]{paths[0], "", "/" + path, paths[0] + "/" + path}; 
     145 
     146    if (resource.startsWith("journals") || resource.startsWith("/journals")) { 
     147      String path = getJournalResourcePath(resource); 
     148      String fullPath = path.startsWith("/") ? path : "/" + path; 
     149 
     150      if (resourceExistsInPath(fullPath)) { 
     151        return new String[]{paths[0], "", fullPath, paths[0] + fullPath}; 
     152      } 
     153    } else if (resourceExistsInServletContext(resource)) { 
     154        return paths; 
    152155    } 
    153156 
     
    156159 
    157160  /** 
    158    * Search in classpath - journal jar files 
    159    * @param resource path to resource 
    160    * @return true if resource exists in classpath 
    161    */ 
    162   private boolean resourceExistsInClasspath(String resource) { 
    163     return Thread.currentThread().getContextClassLoader().getResource(resource) != null; 
     161   * Path /journal/journal-name/resource changes to /journal/journal-name/webapp/resource 
     162   * @param resource Resource path 
     163   * @return Absolute resource path 
     164   */ 
     165  private String getJournalResourcePath(String resource) { 
     166    String templatePath = configuration.getString(ConfigurationStore.JOURNAL_TEMPLATE_DIR, null); 
     167 
     168    StringTokenizer tokenizer = new StringTokenizer(resource,"/"); 
     169    StringBuilder stringBuilder = new StringBuilder(); 
     170    boolean addWebapp = false; 
     171    while(tokenizer.hasMoreTokens()) { 
     172      String token = tokenizer.nextToken(); 
     173      if (token.equals("journals") && stringBuilder.length() == 0) { 
     174        addWebapp = true; 
     175      } 
     176      stringBuilder.append('/').append(token); 
     177      if (addWebapp && !token.equals("journals")) { 
     178        stringBuilder.append("/webapp"); 
     179        addWebapp = false; 
     180      } 
     181    } 
     182 
     183    return templatePath + stringBuilder.toString(); 
    164184  } 
    165185 
     
    179199 
    180200  /** 
     201   * Search in file system 
     202   * @param resource path to resource 
     203   * @return true if resource exists in servlet context 
     204   * @throws ServletException Servlet exception 
     205   */ 
     206  private boolean resourceExistsInPath(String resource) throws ServletException { 
     207    File file = new File(resource); 
     208    return file.isFile() && file.canRead(); 
     209  } 
     210 
     211  /** 
    181212   * Wrap an HttpServletRequest with arbitrary URI values. 
    182213   * 
  • head/ambra/webapp/src/main/resources/ambra/configuration/defaults.xml

    r7764 r7771  
    8080    <!-- virtual journal config --> 
    8181    <virtualJournals> 
     82      <!-- Location of journal template files --> 
     83      <templateDir>/var/ambra</templateDir> 
    8284      <!-- config for default journal --> 
    8385      <default>AmbraJournal</default> 
  • head/ambra/webapp/src/main/webapp/WEB-INF/applicationContext.xml

    r7764 r7771  
    369369    <constructor-arg index="0" ref="ambraConfiguration"/> 
    370370  </bean> 
    371   <bean id="ambraFreemarkerManager" class="org.topazproject.ambra.struts2.AmbraFreemarkerManager"> 
    372     <constructor-arg index="0" ref="ambraFreemarkerConfig"/> 
    373   </bean> 
     371 
     372  <bean id="ambraFreemarkerManager" class="org.topazproject.ambra.struts2.AmbraFreemarkerManager" /> 
    374373 
    375374  <!-- Caches --> 
  • head/ambra/webapp/src/main/webapp/WEB-INF/web.xml

    r6938 r7771  
    122122  </filter> 
    123123 
     124  <filter> 
     125    <filter-name>journalStaticResources</filter-name> 
     126    <filter-class>org.topazproject.ambra.web.JournalStaticResourceFilter</filter-class> 
     127  </filter> 
     128 
    124129  <filter-mapping> 
    125130    <filter-name>MultipleRequestFilter</filter-name> 
     
    222227    <dispatcher>REQUEST</dispatcher> 
    223228    <dispatcher>FORWARD</dispatcher> 
     229  </filter-mapping> 
     230 
     231  <filter-mapping> 
     232    <filter-name>journalStaticResources</filter-name> 
     233    <url-pattern>/*</url-pattern> 
     234    <dispatcher>REQUEST</dispatcher> 
     235    <dispatcher>FORWARD</dispatcher> 
     236    <dispatcher>ERROR</dispatcher> 
    224237  </filter-mapping> 
    225238 
     
    245258  </listener> 
    246259 
    247   <servlet> 
    248     <servlet-name>freemarker</servlet-name> 
    249     <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> 
    250  
    251     <!-- FreemarkerServlet settings: --> 
    252     <init-param> 
    253       <param-name>TemplatePath</param-name> 
    254       <param-value>/</param-value> 
    255     </init-param> 
    256     <init-param> 
    257       <param-name>NoCache</param-name> 
    258       <param-value>true</param-value> 
    259     </init-param> 
    260     <init-param> 
    261       <param-name>ContentType</param-name> 
    262       <param-value>text/html</param-value> 
    263     </init-param> 
    264  
    265     <!-- FreeMarker settings: --> 
    266     <init-param> 
    267       <param-name>default_encoding</param-name> 
    268       <param-value>UTF-8</param-value> 
    269     </init-param> 
    270     <init-param> 
    271       <param-name>output_encoding</param-name> 
    272       <param-value>UTF-8</param-value> 
    273     </init-param> 
    274     <init-param> 
    275       <param-name>number_format</param-name> 
    276       <param-value>0.##########</param-value> 
    277     </init-param> 
    278  
    279     <load-on-startup>1</load-on-startup> 
    280   </servlet> 
    281  
    282   <servlet-mapping> 
    283     <servlet-name>freemarker</servlet-name> 
    284     <url-pattern>*.ftl</url-pattern> 
    285   </servlet-mapping> 
    286  
    287260  <welcome-file-list> 
    288261    <welcome-file>index.jsp</welcome-file>