View Javadoc
1   /*
2    * Copyright (c) 2012-2023, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.mysql.maven.plugin;
31  
32  import com.jcabi.aspects.Cacheable;
33  import com.jcabi.log.Logger;
34  import java.io.File;
35  import java.util.Collections;
36  import java.util.List;
37  import lombok.EqualsAndHashCode;
38  import lombok.ToString;
39  import org.apache.maven.plugin.AbstractMojo;
40  import org.apache.maven.plugin.MojoFailureException;
41  import org.apache.maven.plugins.annotations.Parameter;
42  import org.apache.maven.project.MavenProject;
43  import org.slf4j.impl.StaticLoggerBinder;
44  
45  /**
46   * Abstract MOJO.
47   * @since 0.1
48   */
49  @ToString
50  @EqualsAndHashCode(callSuper = false)
51  abstract class AbstractMysqlMojo extends AbstractMojo {
52  
53      /**
54       * Property that will be exported by the plugin indicating if an existing
55       * database could be reused.
56       */
57      private static final String PROPERTY_REUSED = "jcabi.reused.database";
58  
59      /**
60       * The Maven project.
61       */
62      @Parameter(
63          defaultValue = "${project}",
64          readonly = true
65      )
66      private transient MavenProject project;
67  
68      /**
69       * Shall we skip execution?
70       */
71      @Parameter(
72          defaultValue = "false",
73          required = false
74      )
75      private transient boolean skip;
76  
77      /**
78       * Port to use.
79       */
80      @Parameter(
81          defaultValue = "3306",
82          required = false
83      )
84      private transient int port;
85  
86      /**
87       * Location of MySQL distribution.
88       */
89      @Parameter(
90          defaultValue = "${project.build.directory}/mysql-dist",
91          required = true
92      )
93      private transient File dist;
94  
95      /**
96       * Username to use.
97       */
98      @Parameter(
99          defaultValue = "root",
100         required = false
101     )
102     private transient String user;
103 
104     /**
105      * Password to use.
106      */
107     @Parameter(
108         defaultValue = "root",
109         required = false
110     )
111     private transient String password;
112 
113     /**
114      * Database name to use.
115      */
116     @Parameter(
117         defaultValue = "root",
118         required = false
119     )
120     private transient String dbname;
121 
122     /**
123      * Location of MySQL data.
124      */
125     @Parameter(
126         defaultValue = "${project.build.directory}/mysql-data",
127         required = true
128     )
129     private transient File data;
130 
131     /**
132      * Override location of MySQL socket file.  Defaults to
133      * (data dir)/mysql.socket.
134      */
135     @Parameter(required = false)
136     private transient File socket;
137 
138     /**
139      * Shall we always delete an existing database or reuse it?
140      */
141     @Parameter(
142         defaultValue = "true",
143         required = false
144     )
145     private transient boolean erase;
146 
147     /**
148      * Configuration options.
149      */
150     @Parameter(
151         required = false
152     )
153     private transient List<String> options;
154 
155     /**
156      * Set skip option.
157      * @param skp Shall we skip execution?
158      */
159     public void setSkip(final boolean skp) {
160         this.skip = skp;
161     }
162 
163     @Override
164     public void execute() throws MojoFailureException {
165         StaticLoggerBinder.getSingleton().setMavenLog(this.getLog());
166         if (this.skip) {
167             Logger.info(this, "execution skipped because of 'skip' option");
168             return;
169         }
170         this.run(AbstractMysqlMojo.instances());
171         if (this.project == null) {
172             Logger.warn(
173                 this,
174                 "MavenProject not initialized, unable to set property %s",
175                 AbstractMysqlMojo.PROPERTY_REUSED
176             );
177         } else {
178             Logger.info(
179                 this,
180                 "set Maven property %s = %s ",
181                 AbstractMysqlMojo.PROPERTY_REUSED,
182                 AbstractMysqlMojo.instances().reusedExistingDatabase()
183             );
184             this.project.getProperties().setProperty(
185                 AbstractMysqlMojo.PROPERTY_REUSED,
186                 Boolean.toString(
187                     AbstractMysqlMojo.instances().reusedExistingDatabase()
188                 )
189             );
190         }
191     }
192 
193     /**
194      * Get directory with MySQL dist.
195      * @return Directory
196      * @throws MojoFailureException If fails
197      */
198     public File distDir() throws MojoFailureException {
199         if (!this.dist.exists()) {
200             throw new MojoFailureException(
201                 String.format(
202                     "MySQL distribution directory doesn't exist: %s", this.dist
203                 )
204             );
205         }
206         return this.dist;
207     }
208 
209     /**
210      * Get directory with MySQL data.
211      * @return Directory
212      */
213     public File dataDir() {
214         return this.data;
215     }
216 
217     /**
218      * Get MySQL socket location.
219      * @return Overridden socket location (null for default)
220      */
221     public File socketFile() {
222         return this.socket;
223     }
224 
225     /**
226      * If true, always delete existing database files and create a new instance
227      * from scratch. If false, try to reuse existing files.
228      * @return If existing database files should be deleted.
229      */
230     public boolean clear() {
231         return this.erase;
232     }
233 
234     /**
235      * Get configuration.
236      * @return Configuration
237      */
238     public Config config() {
239         if (this.options == null) {
240             this.options = Collections.emptyList();
241         }
242         return new Config(
243             this.port, this.user, this.password, this.dbname,
244             Collections.unmodifiableList(this.options)
245         );
246     }
247 
248     /**
249      * Run custom functionality.
250      * @param instances Instances to work with
251      * @throws MojoFailureException If fails
252      */
253     protected abstract void run(Instances instances) throws MojoFailureException;
254 
255     /**
256      * Get instances.
257      * @return Instances
258      */
259     @Cacheable(forever = true)
260     private static Instances instances() {
261         return new Instances();
262     }
263 
264 }