001/* 002 * Copyright c 2018 Rusi Popov, MDA Tools.net All rights reserved. 003 * 004 * This program and the accompanying materials are made available under the terms of the 005 * Eclipse Public License v2.0 which accompanies this distribution, and is available at 006 * http://www.eclipse.org/legal/epl-v20.html 007 */ 008package net.mdatools.modelant.core.wrap; 009 010import java.io.Serializable; 011import java.util.Collection; 012import java.util.List; 013 014import net.mdatools.modelant.core.api.wrap.Wrapper; 015import net.mdatools.modelant.core.api.wrap.WrapperFactory; 016 017 018/** 019 * <b>This class is the root class for all wrapper classes.</b><br> 020 * INVARIANT:<ul> 021 * <li> the wrapped object is never null 022 * <li> the factory object is never null 023 * <li> the factory is exactly one that created this object 024 * </ul> 025 * Additional methods (not related actually to the wrapping function of this class) are added to ease the 026 * use of this class for code generation. 027 * @author Rusi Popov (popovr@mdatools.net) 028 */ 029public abstract class BaseWrapper<A> implements Serializable, Wrapper<A> { 030 031 /** 032 * The object this wrapper class wraps to allow its rendering. The reflective 033 * interface of the model element is used in oder to make this class 034 * independent of the actual model and interface. 035 */ 036 private final A wrapped; 037 038 /** 039 * This is the factory the subclasses must use to build wrappers of 040 * the model objects reachable through the current wrapped model object. 041 * It makes sure the proper class is instantiated reflecting the actual 042 * interface of the model object. 043 */ 044 private final WrapperFactory factory; 045 046 /** 047 * @param wrapped is non-null object to wrap 048 * @param factory is the non-null factory that created this 049 */ 050 protected BaseWrapper(A wrapped, WrapperFactory factory) { 051 052 assert wrapped != null : "Expected a non-null wrapped object"; 053 assert factory != null : "Expected a non-null factory"; 054 055 this.wrapped = wrapped; 056 this.factory = factory; 057 } 058 059 060 /** 061 * CONVENTION:<ul> 062 * <li> when the wrapper is used to create a new wrapped object, it might happen that this method needs public access. 063 * <li> when wrapping a wrapper, this method is overridden, this way granting the outer-most wrapper 064 * access to the nested-most wrapped object (bypassing the wrappers) 065 * </ul> 066 * @return the deepest wrapped object 067 */ 068 public final A getWrapped() { 069 return wrapped; 070 } 071 072 /** 073 * The factory for this instance 074 * @return the wrapper factory this was constructed with 075 */ 076 protected final WrapperFactory getFactory() { 077 return factory; 078 } 079 080 /** 081 * Call this method in subclasses in order to instantiate the wrapper class 082 * that actually corresponds to the class of the object toWrap 083 * @param toWrap is the object to wrap in another wrapper class. Might be null; 084 * @return null, when null provided, otherwise a properly initialized 085 * wrapper class that wraps toWrap 086 * @throws IllegalArgumentException when mapping is not possible 087 * @see Wrapper#wrap(Object) 088 */ 089 public final Wrapper<A> wrap(A toWrap) throws IllegalArgumentException { 090 return factory.wrap( toWrap ); 091 } 092 093 /** 094 * Call this method in subclasses in order to instantiate the wrapper class 095 * that actually corresponds to the class of the object toWrap 096 * @param toWrap is the object to wrap in another wrapper class. Might be null; 097 * @return null, when null provided, otherwise a properly initialized 098 * collection of wrappers that wrap the elements of toWrap 099 * @throws IllegalArgumentException when mapping is not possible 100 * @see Wrapper#wrap(Collection) 101 */ 102 public final List<Wrapper<A>> wrap(Collection<A> toWrap) throws IllegalArgumentException { 103 return factory.wrap( toWrap ); 104 } 105}