001/*
002 * Copyright 2012-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.boot.loader.tools;
018
019import java.io.File;
020import java.util.Arrays;
021import java.util.Collections;
022import java.util.HashMap;
023import java.util.HashSet;
024import java.util.Map;
025import java.util.Set;
026
027/**
028 * Common {@link Layout}s.
029 *
030 * @author Phillip Webb
031 * @author Dave Syer
032 * @author Andy Wilkinson
033 */
034public final class Layouts {
035
036        private Layouts() {
037        }
038
039        /**
040         * Return a layout for the given source file.
041         * @param file the source file
042         * @return a {@link Layout}
043         */
044        public static Layout forFile(File file) {
045                if (file == null) {
046                        throw new IllegalArgumentException("File must not be null");
047                }
048                if (file.getName().toLowerCase().endsWith(".jar")) {
049                        return new Jar();
050                }
051                if (file.getName().toLowerCase().endsWith(".war")) {
052                        return new War();
053                }
054                if (file.isDirectory() || file.getName().toLowerCase().endsWith(".zip")) {
055                        return new Expanded();
056                }
057                throw new IllegalStateException("Unable to deduce layout for '" + file + "'");
058        }
059
060        /**
061         * Executable JAR layout.
062         */
063        public static class Jar implements RepackagingLayout {
064
065                @Override
066                public String getLauncherClassName() {
067                        return "org.springframework.boot.loader.JarLauncher";
068                }
069
070                @Override
071                public String getLibraryDestination(String libraryName, LibraryScope scope) {
072                        return "BOOT-INF/lib/";
073                }
074
075                @Override
076                public String getClassesLocation() {
077                        return "";
078                }
079
080                @Override
081                public String getRepackagedClassesLocation() {
082                        return "BOOT-INF/classes/";
083                }
084
085                @Override
086                public boolean isExecutable() {
087                        return true;
088                }
089
090        }
091
092        /**
093         * Executable expanded archive layout.
094         */
095        public static class Expanded extends Jar {
096
097                @Override
098                public String getLauncherClassName() {
099                        return "org.springframework.boot.loader.PropertiesLauncher";
100                }
101
102        }
103
104        /**
105         * No layout.
106         */
107        public static class None extends Jar {
108
109                @Override
110                public String getLauncherClassName() {
111                        return null;
112                }
113
114                @Override
115                public boolean isExecutable() {
116                        return false;
117                }
118
119        }
120
121        /**
122         * Executable WAR layout.
123         */
124        public static class War implements Layout {
125
126                private static final Map<LibraryScope, String> scopeDestinations;
127
128                static {
129                        Map<LibraryScope, String> map = new HashMap<LibraryScope, String>();
130                        map.put(LibraryScope.COMPILE, "WEB-INF/lib/");
131                        map.put(LibraryScope.CUSTOM, "WEB-INF/lib/");
132                        map.put(LibraryScope.RUNTIME, "WEB-INF/lib/");
133                        map.put(LibraryScope.PROVIDED, "WEB-INF/lib-provided/");
134                        scopeDestinations = Collections.unmodifiableMap(map);
135                }
136
137                @Override
138                public String getLauncherClassName() {
139                        return "org.springframework.boot.loader.WarLauncher";
140                }
141
142                @Override
143                public String getLibraryDestination(String libraryName, LibraryScope scope) {
144                        return scopeDestinations.get(scope);
145                }
146
147                @Override
148                public String getClassesLocation() {
149                        return "WEB-INF/classes/";
150                }
151
152                @Override
153                public boolean isExecutable() {
154                        return true;
155                }
156
157        }
158
159        /**
160         * Module layout (designed to be used as a "plug-in").
161         * @deprecated as of 1.5 in favor of a custom {@link LayoutFactory}
162         */
163        @Deprecated
164        public static class Module implements Layout {
165
166                private static final Set<LibraryScope> LIB_DESTINATION_SCOPES = new HashSet<LibraryScope>(
167                                Arrays.asList(LibraryScope.COMPILE, LibraryScope.RUNTIME,
168                                                LibraryScope.CUSTOM));
169
170                @Override
171                public String getLauncherClassName() {
172                        return null;
173                }
174
175                @Override
176                public String getLibraryDestination(String libraryName, LibraryScope scope) {
177                        if (LIB_DESTINATION_SCOPES.contains(scope)) {
178                                return "lib/";
179                        }
180                        return null;
181                }
182
183                @Override
184                public String getClassesLocation() {
185                        return "";
186                }
187
188                @Override
189                public boolean isExecutable() {
190                        return false;
191                }
192
193        }
194
195}