001/* 002 * (C) Copyright 2010-2013 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Olivier Grisel 018 */ 019package org.nuxeo.ecm.platform.suggestbox.service.descriptors; 020 021import java.util.HashMap; 022import java.util.Map; 023 024import org.nuxeo.common.xmap.annotation.XNode; 025import org.nuxeo.common.xmap.annotation.XNodeMap; 026import org.nuxeo.common.xmap.annotation.XObject; 027import org.nuxeo.ecm.platform.suggestbox.service.ComponentInitializationException; 028import org.nuxeo.ecm.platform.suggestbox.service.Suggester; 029import org.nuxeo.runtime.model.RuntimeContext; 030 031/** 032 * XMap descriptor for registering overridable parameterized Suggester implementation on the SuggesterService. 033 * 034 * @author ogrisel 035 */ 036@XObject("suggester") 037public class SuggesterDescriptor implements Cloneable { 038 039 @XNode("@name") 040 protected String name = "default"; 041 042 @XNode("@class") 043 protected String className; 044 045 @XNode("@enabled") 046 protected boolean enabled = true; 047 048 @XNodeMap(value = "parameters/parameter", key = "@name", type = HashMap.class, componentType = String.class) 049 protected Map<String, String> parameters = new HashMap<String, String>(); 050 051 protected Suggester suggester; 052 053 protected RuntimeContext runtimeContext; 054 055 public String getName() { 056 return name; 057 } 058 059 public boolean isEnabled() { 060 return enabled; 061 } 062 063 public Map<String, String> getParameters() { 064 return parameters; 065 } 066 067 public void setRuntimeContext(RuntimeContext context) throws ComponentInitializationException { 068 // store the runtime context for later usage if a merge is required 069 this.runtimeContext = context; 070 loadParameterizedSuggester(); 071 } 072 073 protected void loadParameterizedSuggester() throws ComponentInitializationException { 074 if (enabled && className != null) { 075 // try build the suggester instance as early as possible to throw 076 // errors at deployment time rather than lazily at first access time 077 // by the user: fail early. 078 try { 079 suggester = (Suggester) runtimeContext.loadClass(className).newInstance(); 080 } catch (ReflectiveOperationException e) { 081 throw new ComponentInitializationException(String.format( 082 "Failed to initialize suggester '%s' with class '%s'", name, className), e); 083 } 084 suggester.initWithParameters(this); 085 } 086 // if the the descriptor is enabled but does not provide any 087 // contrib this is probably just for overriding some parameters 088 // handled at merge time 089 } 090 091 public Suggester getSuggester() { 092 return suggester; 093 } 094 095 public void mergeFrom(SuggesterDescriptor newDescriptor) throws ComponentInitializationException { 096 if (name == null || !name.equals(newDescriptor.name)) { 097 throw new RuntimeException("Cannot merge descriptor with name '" + name 098 + "' with another descriptor with different name " + newDescriptor.getName() + "'"); 099 } 100 if (className == null) { 101 if (enabled && newDescriptor.className == null) { 102 throw new RuntimeException("Cannot merge descriptor with name '" + name 103 + "' with source a source version that has no" + " className defined."); 104 } 105 className = newDescriptor.className; 106 runtimeContext = newDescriptor.runtimeContext; 107 } 108 // merged the parameters 109 Map<String, String> mergedParameters = new HashMap<String, String>(); 110 mergedParameters.putAll(parameters); 111 mergedParameters.putAll(newDescriptor.parameters); 112 parameters = mergedParameters; 113 loadParameterizedSuggester(); 114 } 115 116 /* 117 * Override the Object.clone to make it public 118 */ 119 @Override 120 public Object clone() throws CloneNotSupportedException { 121 return super.clone(); 122 } 123 124}