/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 *
 */
package org.xwiki.velocity.internal;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.xwiki.component.annotation.Component;
import org.xwiki.component.annotation.Requirement;
import org.xwiki.component.logging.AbstractLogEnabled;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.management.JMXBeanRegistration;
import org.xwiki.velocity.VelocityEngine;
import org.xwiki.velocity.VelocityFactory;
import org.xwiki.velocity.XWikiVelocityException;
import org.xwiki.velocity.internal.jmx.JMXVelocityEngine;
import org.xwiki.velocity.internal.jmx.JMXVelocityEngineMBean;

/**
 * Default implementation for {@link VelocityFactory}.
 * 
 * @see VelocityFactory
 * @version $Id$
 */
@Component
public class DefaultVelocityFactory extends AbstractLogEnabled implements VelocityFactory
{
    /**
     * The Component manager we use to lookup (and thus create since it's a singleton) the VelocityEngine component.
     */
    @Requirement
    private ComponentManager componentManager;

    /**
     * In order to register the Velocity MBean for management.
     */
    @Requirement
    private JMXBeanRegistration jmxRegistration;

    /**
     * A cache of Velocity Engines. See {@link org.xwiki.velocity.VelocityFactory} for more details as to why we need
     * this cache.
     */
    private Map<String, VelocityEngine> velocityEngines = new HashMap<String, VelocityEngine>();

    /**
     * {@inheritDoc}
     * 
     * @see VelocityFactory#hasVelocityEngine(String)
     */
    public boolean hasVelocityEngine(String key)
    {
        return this.velocityEngines.containsKey(key);
    }

    /**
     * {@inheritDoc}
     * 
     * @see VelocityFactory#getVelocityEngine(String)
     */
    public VelocityEngine getVelocityEngine(String key)
    {
        return this.velocityEngines.get(key);
    }

    /**
     * {@inheritDoc}
     * 
     * @see VelocityFactory#createVelocityEngine(String, Properties)
     */
    public VelocityEngine createVelocityEngine(String key, Properties properties) throws XWikiVelocityException
    {
        VelocityEngine engine;
        if (this.velocityEngines.containsKey(key)) {
            engine = this.velocityEngines.get(key);
        } else {
            try {
                engine = this.componentManager.lookup(VelocityEngine.class);
            } catch (ComponentLookupException e) {
                throw new XWikiVelocityException("Failed to create Velocity Engine", e);
            }
            engine.initialize(properties);
            this.velocityEngines.put(key, engine);
        }

        // Register a JMX MBean for providing information about the created Velocity Engine (template namespaces,
        // macros, etc).
        JMXVelocityEngineMBean mbean = new JMXVelocityEngine(engine);
        this.jmxRegistration.registerMBean(mbean, "type=Velocity,domain=Engines,name=" + key);

        return engine;
    }
}

@@ -3044,24 +3044,74 @@
 ption%0A    %7B%0A
+        synchronized (this.velocityEngines) %7B%0A    
         Velo
@@ -3125,24 +3125,28 @@
 ine engine;%0A
+    
         if (
@@ -3190,32 +3190,36 @@
 ) %7B%0A            
+ 
+   
 engine = this.ve
@@ -3238,24 +3238,28 @@
 s.get(key);%0A
+    
         %7D el
@@ -3279,14 +3279,22 @@
     
+    
 try %7B%0A
+    
     
@@ -3378,16 +3378,20 @@
         
+    
 %7D catch 
@@ -3417,24 +3417,28 @@
 eption e) %7B%0A
+    
             
@@ -3526,18 +3526,26 @@
         
-%7D%0A
+    %7D%0A    
         
@@ -3587,24 +3587,28 @@
             
+    
 this.velocit
@@ -3638,27 +3638,35 @@
 e);%0A        
+   
+ 
 %7D%0A%0A
+    
         // R
@@ -3775,16 +3775,20 @@
         
+    
 // macro
@@ -3796,16 +3796,20 @@
 , etc).%0A
+    
         
@@ -3874,24 +3874,28 @@
 e);%0A        
+   
+ 
 this.jmxRegi
@@ -3974,24 +3974,28 @@
 );%0A%0A        
+    
 return engin
@@ -3993,20 +3993,30 @@
 urn engine;%0A
+        %7D%0A
     %7D%0A%7D%0A

Make sure that we have a single velocity engine created per given key (before this fix the Lucene rebuild thread was fighting with the main doc thread and they were creating 2 instances of the velocity engine for "default").