View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.benerator.composite;
28  
29  import com.rapiddweller.benerator.BeneratorConstants;
30  import com.rapiddweller.benerator.GeneratorContext;
31  import com.rapiddweller.benerator.engine.BeneratorContext;
32  import com.rapiddweller.benerator.wrapper.ProductWrapper;
33  import com.rapiddweller.common.MessageHolder;
34  import com.rapiddweller.common.Resettable;
35  import com.rapiddweller.common.ThreadAware;
36  import com.rapiddweller.common.ThreadUtil;
37  import org.apache.logging.log4j.LogManager;
38  import org.apache.logging.log4j.Logger;
39  
40  import java.io.Closeable;
41  import java.util.ArrayList;
42  import java.util.List;
43  
44  /**
45   * Offers support for entity or array component generation with or without variable generation.<br/><br/>
46   * Created: 13.01.2011 10:52:43
47   *
48   * @param <E> the type parameter
49   * @author Volker Bergmann
50   * @since 0.6.4
51   */
52  public class ComponentAndVariableSupport<E> implements ThreadAware, MessageHolder, Resettable, Closeable {
53  
54    private static final Logger LOGGER = LogManager.getLogger(ComponentAndVariableSupport.class);
55    private static final Logger STATE_LOGGER = LogManager.getLogger(BeneratorConstants.STATE_LOGGER);
56  
57    private final String instanceName;
58    private final List<GeneratorComponent<E>> components;
59    private String message;
60  
61    /**
62     * Instantiates a new Component and variable support.
63     *
64     * @param instanceName the instance name
65     * @param components   the components
66     * @param context      the context
67     */
68    public ComponentAndVariableSupport(String instanceName, List<GeneratorComponent<E>> components,
69                                       GeneratorContext context) {
70      this.instanceName = instanceName;
71      this.components = (components != null ? components : new ArrayList<>());
72    }
73  
74    /**
75     * Init.
76     *
77     * @param context the context
78     */
79    public void init(BeneratorContext context) {
80      for (GeneratorComponent<?> component : components) {
81        component.init(context);
82      }
83    }
84  
85    /**
86     * Apply boolean.
87     *
88     * @param target  the target
89     * @param context the context
90     * @return the boolean
91     */
92    public boolean apply(E target, BeneratorContext context) {
93      BeneratorContext subContext = context.createSubContext(instanceName);
94      subContext.setCurrentProduct(new ProductWrapper<>(target));
95      for (GeneratorComponent<E> component : components) {
96        try {
97          if (!component.execute(subContext)) {
98            message = "Component generator for '" + instanceName +
99                "' is not available any longer: " + component;
100           STATE_LOGGER.debug(message);
101           return false;
102         }
103       } catch (Exception e) {
104         throw new RuntimeException("Failure in generation of '" + instanceName + "', " +
105             "Failed component: " + component, e);
106       }
107     }
108     LOGGER.debug("Generated {}", target);
109     subContext.close();
110     return true;
111   }
112 
113   @Override
114   public void reset() {
115     for (GeneratorComponent<E> component : components) {
116       component.reset();
117     }
118   }
119 
120   @Override
121   public void close() {
122     for (GeneratorComponent<E> component : components) {
123       component.close();
124     }
125   }
126 
127   @Override
128   public String getMessage() {
129     return message;
130   }
131 
132 
133   // ThreadAware interface implementation ----------------------------------------------------------------------------
134 
135   @Override
136   public boolean isParallelizable() {
137     return ThreadUtil.allParallelizable(components);
138   }
139 
140   @Override
141   public boolean isThreadSafe() {
142     return ThreadUtil.allThreadSafe(components);
143   }
144 
145 
146   // java.lang.Object overrides --------------------------------------------------------------------------------------
147 
148   @Override
149   public String toString() {
150     return getClass().getSimpleName() + components;
151   }
152 
153 }