001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2010–2011 ApexIdentity Inc. 015 * Portions Copyright 2011-2014 ForgeRock AS. 016 */ 017 018package org.forgerock.openig.heap; 019 020import static org.forgerock.openig.io.TemporaryStorage.*; 021import static org.forgerock.openig.log.LogSink.*; 022 023import java.util.Arrays; 024import java.util.HashSet; 025import java.util.Map; 026import java.util.Set; 027 028import org.forgerock.json.fluent.JsonValue; 029import org.forgerock.openig.io.TemporaryStorage; 030import org.forgerock.openig.log.LogSink; 031import org.forgerock.openig.log.Logger; 032 033/** 034 * A generic base class for heaplets with automatically injected fields. 035 * <p> 036 * If the object created is an instance of {@link GenericHeapObject}, it is then 037 * automatically injected with {@code logger} and {@code storage} objects. 038 */ 039public abstract class GenericHeaplet implements Heaplet { 040 041 /** Heap objects to avoid dependency injection (prevents circular dependencies). */ 042 private static final Set<String> SPECIAL_OBJECTS = 043 new HashSet<String>(Arrays.asList(LOGSINK_HEAP_KEY, TEMPORARY_STORAGE_HEAP_KEY)); 044 045 /** The name of the object to be created and stored in the heap by this heaplet. */ 046 protected String name; 047 048 /** The fully qualified name of the object to be created. */ 049 protected Name qualified; 050 051 /** The heaplet's object configuration object. */ 052 protected JsonValue config; 053 054 /** Where objects should be put and where object dependencies should be retrieved. */ 055 protected Heap heap; 056 057 /** Provides methods for logging activities. */ 058 protected Logger logger; 059 060 /** Allocates temporary buffers for caching streamed content during processing. */ 061 protected TemporaryStorage storage; 062 063 /** The object created by the heaplet's {@link #create()} method. */ 064 protected Object object; 065 066 @Override 067 public Object create(Name name, JsonValue config, Heap heap) throws HeapException { 068 this.name = name.getLeaf(); 069 this.qualified = name; 070 this.config = config.required().expect(Map.class); 071 this.heap = heap; 072 if (!SPECIAL_OBJECTS.contains(this.name)) { 073 this.logger = new Logger( 074 heap.resolve( 075 config.get("logSink").defaultTo(LOGSINK_HEAP_KEY), 076 LogSink.class, true), 077 name); 078 this.storage = heap.resolve( 079 config.get("temporaryStorage").defaultTo(TEMPORARY_STORAGE_HEAP_KEY), 080 TemporaryStorage.class); 081 } 082 this.object = create(); 083 if (this.object instanceof GenericHeapObject) { 084 // instrument object if possible 085 GenericHeapObject ghObject = (GenericHeapObject) this.object; 086 ghObject.logger = this.logger; 087 ghObject.storage = this.storage; 088 } 089 start(); 090 return object; 091 } 092 093 @Override 094 public void destroy() { 095 // default does nothing 096 } 097 098 /** 099 * Called to request the heaplet create an object. Called by 100 * {@link Heaplet#create(Name, JsonValue, Heap)} after initializing 101 * the protected field members. Implementations should parse configuration 102 * but not acquire resources, start threads, or log any initialization 103 * messages. These tasks should be performed by the {@link #start()} method. 104 * 105 * @return The created object. 106 * @throws HeapException 107 * if an exception occurred during creation of the heap object 108 * or any of its dependencies. 109 * @throws org.forgerock.json.fluent.JsonValueException 110 * if the heaplet (or one of its dependencies) has a malformed 111 * configuration. 112 */ 113 public abstract Object create() throws HeapException; 114 115 /** 116 * Called to request the heaplet start an object. Called by 117 * {@link Heaplet#create(Name, JsonValue, Heap)} after creating and 118 * configuring the object and once the object's logger and storage have been 119 * configured. Implementations should override this method if they need to 120 * acquire resources, start threads, or log any initialization messages. 121 * 122 * @throws HeapException 123 * if an exception occurred while starting the heap object or 124 * any of its dependencies. 125 */ 126 public void start() throws HeapException { 127 // default does nothing 128 } 129}