View Javadoc

1   /*
2    * Copyright 2010-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.testdoc.report.export.doc;
17  
18  import java.io.File;
19  import java.io.IOException;
20  import java.io.ObjectInputStream;
21  import java.lang.management.ManagementFactory;
22  import java.util.Collection;
23  
24  import javax.management.JMX;
25  import javax.management.MBeanServer;
26  import javax.management.MalformedObjectNameException;
27  import javax.management.ObjectName;
28  
29  import org.apache.commons.io.FileUtils;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  import de.smartics.testdoc.core.adapter.JmxExportAdapterClient;
34  import de.smartics.testdoc.core.adapter.JmxExportAdapterMBean;
35  import de.smartics.testdoc.core.adapter.PersistenceUtils;
36  import de.smartics.testdoc.core.doc.UnitTestDoc;
37  import de.smartics.testdoc.core.doc.UnitTestDocIndex;
38  
39  /**
40   * Checks whether or not the test documentation has been gathered successfully.
41   * <p>
42   * This is a simple implementation that checks, whether there is accessible
43   * information stored either in the JMX bean or a singleton index of serialized
44   * files.
45   * </p>
46   */
47  public class IndexProvider
48  {
49    // ********************************* Fields *********************************
50  
51    // --- constants ------------------------------------------------------------
52  
53    /**
54     * The logger to use.
55     */
56    private final Logger log = LoggerFactory.getLogger(IndexProvider.class);
57  
58    // --- members --------------------------------------------------------------
59  
60    /**
61     * The name of the JMX bean that provides access to the generated index.
62     */
63    private final ObjectName jmxObjectName;
64  
65    /**
66     * The location where the serialized files with test doc information is
67     * expected.
68     */
69    private final File serializedRootDir;
70  
71    // ****************************** Initializer *******************************
72  
73    // ****************************** Constructors ******************************
74  
75    /**
76     * Convenience constructor using JMX object name
77     * {@link JmxExportAdapterClient#OBJECT_NAME}.
78     *
79     * @param serializedRootDir the location where the serialized files with test
80     *          doc information is expected.
81     * @throws NullPointerException if <code>serDir</code> is <code>null</code>.
82     */
83    public IndexProvider(final String serializedRootDir)
84      throws NullPointerException
85    {
86      this(JmxExportAdapterClient.OBJECT_NAME, serializedRootDir);
87    }
88  
89    /**
90     * Default constructor.
91     *
92     * @param jmxObjectName the name of the JMX bean that provides acces to the
93     *          generated index.
94     * @param serializedRootDir the location where the serialized files with test
95     *          doc information is expected.
96     * @throws IllegalStateException if the <code>jmxObjectName</code> is not
97     *           valid.
98     * @throws NullPointerException if the <code>jmxObjectName</code> or
99     *           <code>serDir</code> is <code>null</code>.
100    */
101   public IndexProvider(final String jmxObjectName,
102       final String serializedRootDir) throws NullPointerException
103   {
104     try
105     {
106       this.jmxObjectName = new ObjectName(jmxObjectName);
107       this.serializedRootDir = new File(serializedRootDir);
108     }
109     catch (final MalformedObjectNameException e)
110     {
111       throw new IllegalStateException("Illegal JMX name: " + jmxObjectName, e);
112     }
113   }
114 
115   // ****************************** Inner Classes *****************************
116 
117   // ********************************* Methods ********************************
118 
119   // --- init -----------------------------------------------------------------
120 
121   // --- get&set --------------------------------------------------------------
122 
123   // --- business -------------------------------------------------------------
124 
125   private boolean isJmxBeanRegistered()
126   {
127     final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
128     final boolean registered = server.isRegistered(jmxObjectName);
129     return registered;
130   }
131 
132   private UnitTestDocIndex getIndexIndexFromJmxBean()
133   {
134     final MBeanServer server = ManagementFactory.getPlatformMBeanServer();
135     final JmxExportAdapterMBean exportAdapter =
136         JMX.newMBeanProxy(server, jmxObjectName, JmxExportAdapterMBean.class);
137     final UnitTestDocIndex index = readIndex(exportAdapter);
138     return index;
139   }
140 
141   private UnitTestDocIndex readIndex(final JmxExportAdapterMBean exportAdapter)
142   {
143     try
144     {
145       final ObjectInputStream in = exportAdapter.getIndexOnStream();
146       if (in != null)
147       {
148         final UnitTestDocIndex index = (UnitTestDocIndex) in.readObject();
149         return index;
150       }
151       return null;
152     }
153     catch (final IOException e)
154     {
155       if (log.isDebugEnabled())
156       {
157         log.debug("Reading the index from the JMX bean failed.", e);
158       }
159       return null;
160     }
161     catch (final ClassNotFoundException e)
162     {
163       if (log.isDebugEnabled())
164       {
165         log.debug("Reading the index from the JMX bean failed.", e);
166       }
167       return null;
168     }
169   }
170 
171   private UnitTestDocIndex readIndex()
172   {
173     final UnitTestDocIndex index = new UnitTestDocIndex(); // GlobalUnitTestDocIndex.getIndex();
174     if (isJmxBeanRegistered())
175     {
176       return getIndexIndexFromJmxBean();
177     }
178     else if (isSerializedIndexProvided())
179     {
180       final Collection<File> serFiles = fetchSerFiles(serializedRootDir);
181       final PersistenceUtils persist = new PersistenceUtils();
182 
183       for (final File serFile : serFiles)
184       {
185         final UnitTestDoc testDoc = (UnitTestDoc) persist.deserialize(serFile);
186         index.register(testDoc);
187       }
188     }
189     if (index.isEmpty())
190     {
191       if (log.isInfoEnabled())
192       {
193         log.info("No index found. Nothing to render to the testdoc report.");
194       }
195       return null;
196     }
197 
198     return index;
199   }
200 
201   private Collection<File> fetchSerFiles(final File baseDir)
202   {
203     return FileUtils.listFiles(baseDir, new String[]
204     { "ser" }, true);
205   }
206 
207   private boolean isSerializedIndexProvided()
208   {
209     return serializedRootDir.exists() && serializedRootDir.list().length > 0;
210   }
211 
212   /**
213    * Creates the helper that essentially encapsulates the index of test
214    * documentation.
215    *
216    * @param config the configuration to be used by the helper.
217    * @return the created helper instance.
218    */
219   public TestDocHelper createHelper(final ReportConfig config)
220   {
221     final UnitTestDocIndex index = readIndex();
222     return new TestDocHelper(index, config);
223   }
224 
225   // --- object basics --------------------------------------------------------
226 
227 }