1 /*
2  * Copyright 2010-2020 Redgate Software Ltd
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 org.flywaydb.core.internal.util;
17
18 import org.flywaydb.core.api.Location;
19 import org.flywaydb.core.api.logging.Log;
20 import org.flywaydb.core.api.logging.LogFactory;
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
25
26 /**
27  * Encapsulation of a location list.
28  */

29 public class Locations {
30     private static final Log LOG = LogFactory.getLog(Locations.class);
31
32     /**
33      * The backing list.
34      */

35     private final List<Location> locations = new ArrayList<>();
36
37     /**
38      * Creates a new Locations wrapper with these raw locations.
39      *
40      * @param rawLocations The raw locations to process.
41      */

42     public Locations(String... rawLocations) {
43         List<Location> normalizedLocations = new ArrayList<>();
44         for (String rawLocation : rawLocations) {
45             normalizedLocations.add(new Location(rawLocation));
46         }
47         processLocations(normalizedLocations);
48     }
49
50     /**
51      * Creates a new Locations wrapper with these locations.
52      *
53      * @param rawLocations The locations to process.
54      */

55     public Locations(List<Location> rawLocations) {
56         processLocations(rawLocations);
57     }
58
59     private void processLocations(List<Location> rawLocations) {
60         List<Location> sortedLocations = new ArrayList<>(rawLocations);
61         Collections.sort(sortedLocations);
62
63         for (Location normalizedLocation : sortedLocations) {
64             if (locations.contains(normalizedLocation)) {
65                 LOG.warn("Discarding duplicate location '" + normalizedLocation + "'");
66                 continue;
67             }
68
69             Location parentLocation = getParentLocationIfExists(normalizedLocation, locations);
70             if (parentLocation != null) {
71                 LOG.warn("Discarding location '" + normalizedLocation + "' as it is a sublocation of '" + parentLocation + "'");
72                 continue;
73             }
74
75             locations.add(normalizedLocation);
76         }
77     }
78
79     /**
80      * @return The locations.
81      */

82     public List<Location> getLocations() {
83         return locations;
84     }
85
86     /**
87      * Retrieves this location's parent within this list, if any.
88      *
89      * @param location       The location to check.
90      * @param finalLocations The list to search.
91      * @return The parent location. {@code nullif none.
92      */

93     private Location getParentLocationIfExists(Location location, List<Location> finalLocations) {
94         for (Location finalLocation : finalLocations) {
95             if (finalLocation.isParentOf(location)) {
96                 return finalLocation;
97             }
98         }
99         return null;
100     }
101 }