001/* 002 * (C) Copyright 2010-2013 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Olivier Grisel 016 */ 017package org.nuxeo.ecm.platform.suggestbox.service.descriptors; 018 019import java.util.HashMap; 020import java.util.Map; 021 022import org.nuxeo.common.xmap.annotation.XNode; 023import org.nuxeo.common.xmap.annotation.XNodeMap; 024import org.nuxeo.common.xmap.annotation.XObject; 025import org.nuxeo.ecm.platform.suggestbox.service.ComponentInitializationException; 026import org.nuxeo.ecm.platform.suggestbox.service.Suggester; 027import org.nuxeo.runtime.model.RuntimeContext; 028 029/** 030 * XMap descriptor for registering overridable parameterized Suggester implementation on the SuggesterService. 031 * 032 * @author ogrisel 033 */ 034@XObject("suggester") 035public class SuggesterDescriptor implements Cloneable { 036 037 @XNode("@name") 038 protected String name = "default"; 039 040 @XNode("@class") 041 protected String className; 042 043 @XNode("@enabled") 044 protected boolean enabled = true; 045 046 @XNodeMap(value = "parameters/parameter", key = "@name", type = HashMap.class, componentType = String.class) 047 protected Map<String, String> parameters = new HashMap<String, String>(); 048 049 protected Suggester suggester; 050 051 protected RuntimeContext runtimeContext; 052 053 public String getName() { 054 return name; 055 } 056 057 public boolean isEnabled() { 058 return enabled; 059 } 060 061 public Map<String, String> getParameters() { 062 return parameters; 063 } 064 065 public void setRuntimeContext(RuntimeContext context) throws ComponentInitializationException { 066 // store the runtime context for later usage if a merge is required 067 this.runtimeContext = context; 068 loadParameterizedSuggester(); 069 } 070 071 protected void loadParameterizedSuggester() throws ComponentInitializationException { 072 if (enabled && className != null) { 073 // try build the suggester instance as early as possible to throw 074 // errors at deployment time rather than lazily at first access time 075 // by the user: fail early. 076 try { 077 suggester = (Suggester) runtimeContext.loadClass(className).newInstance(); 078 } catch (ReflectiveOperationException e) { 079 throw new ComponentInitializationException(String.format( 080 "Failed to initialize suggester '%s' with class '%s'", name, className), e); 081 } 082 suggester.initWithParameters(this); 083 } 084 // if the the descriptor is enabled but does not provide any 085 // contrib this is probably just for overriding some parameters 086 // handled at merge time 087 } 088 089 public Suggester getSuggester() { 090 return suggester; 091 } 092 093 public void mergeFrom(SuggesterDescriptor newDescriptor) throws ComponentInitializationException { 094 if (name == null || !name.equals(newDescriptor.name)) { 095 throw new RuntimeException("Cannot merge descriptor with name '" + name 096 + "' with another descriptor with different name " + newDescriptor.getName() + "'"); 097 } 098 if (className == null) { 099 if (enabled && newDescriptor.className == null) { 100 throw new RuntimeException("Cannot merge descriptor with name '" + name 101 + "' with source a source version that has no" + " className defined."); 102 } 103 className = newDescriptor.className; 104 runtimeContext = newDescriptor.runtimeContext; 105 } 106 // merged the parameters 107 Map<String, String> mergedParameters = new HashMap<String, String>(); 108 mergedParameters.putAll(parameters); 109 mergedParameters.putAll(newDescriptor.parameters); 110 parameters = mergedParameters; 111 loadParameterizedSuggester(); 112 } 113 114 /* 115 * Override the Object.clone to make it public 116 */ 117 @Override 118 public Object clone() throws CloneNotSupportedException { 119 return super.clone(); 120 } 121 122}