001/**
002 * Copyright 2010-2014 The Kuali Foundation
003 *
004 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php
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 */
016package org.kuali.common.util.project.model;
017
018import static com.google.common.base.Preconditions.checkArgument;
019import static com.google.common.base.Preconditions.checkNotNull;
020
021import java.io.File;
022
023import org.apache.commons.lang3.StringUtils;
024import org.kuali.common.util.file.CanonicalFile;
025import org.kuali.common.util.metainf.service.MetaInfUtils;
026import org.springframework.util.ResourceUtils;
027
028public final class ProjectResource {
029
030        private final String prefix;
031        private final ProjectIdentifier project;
032        private final String path;
033
034        private ProjectResource(Builder builder) {
035                this.project = builder.project;
036                this.prefix = builder.prefix;
037                this.path = builder.path;
038        }
039
040        /**
041         * Create a {@code ProjectResource} with the prefix set to {@code classpath:}
042         */
043        public static ProjectResource create(ProjectIdentifier project, String path) {
044                return builder(project, path).build();
045        }
046
047        /**
048         * Create a {@code ProjectResource} with the corresponding prefix
049         */
050        public static ProjectResource create(String prefix, ProjectIdentifier project, String path) {
051                return builder(project, path).prefix(prefix).build();
052        }
053
054        /**
055         * Create a {@code ProjectResource} with the prefix set to {@code classpath:}
056         */
057        public static ProjectResource classpath(ProjectIdentifier project, String path) {
058                return classpath(project, path, false);
059        }
060
061        /**
062         * Create a {@code ProjectResource} with the prefix set to {@code classpath:} or {@code classpath:META-INF/}
063         */
064        public static ProjectResource classpath(ProjectIdentifier project, String path, boolean metainf) {
065                return builder(project, path).classpathPrefix(metainf).build();
066        }
067
068        /**
069         * Create a {@code ProjectResource} with the prefix set to {@code directory} and optionally further prefixed with {@code META-INF}
070         */
071        public static ProjectResource directory(File directory, ProjectIdentifier project, String path, boolean metainf) {
072                return builder(project, path).directoryPrefix(directory, metainf).build();
073        }
074
075        /**
076         * Create a {@code ProjectResource} with the prefix set to {@code directory}
077         */
078        public static ProjectResource directory(File directory, ProjectIdentifier project, String path) {
079                return directory(directory, project, path, false);
080        }
081
082        public static Builder builder(ProjectIdentifier project, String path) {
083                return new Builder(project, path);
084        }
085
086        public static class Builder {
087
088                // Required
089                private final ProjectIdentifier project;
090                private final String path;
091
092                // Optional
093                private String prefix = ResourceUtils.CLASSPATH_URL_PREFIX;
094
095                public Builder(ProjectIdentifier project, String path) {
096                        this.project = project;
097                        this.path = path;
098                }
099
100                /**
101                 * {@code classpath:}
102                 */
103                public Builder classpathPrefix() {
104                        return prefix(ResourceUtils.CLASSPATH_URL_PREFIX);
105                }
106
107                /**
108                 * {@code classpath:} or {@code classpath:META-INF/}
109                 */
110                public Builder classpathPrefix(boolean metainf) {
111                        if (metainf) {
112                                return prefix(ResourceUtils.CLASSPATH_URL_PREFIX + MetaInfUtils.METAINF_DIRECTORY_NAME + "/");
113                        } else {
114                                return classpathPrefix();
115                        }
116                }
117
118                /**
119                 * {@code /tmp/}
120                 */
121                public Builder directoryPrefix(File directory) {
122                        return directoryPrefix(directory, false);
123                }
124
125                /**
126                 * {@code /tmp/} or {@code /tmp/META-INF/}
127                 */
128                public Builder directoryPrefix(File directory, boolean metainf) {
129                        String path = new CanonicalFile(directory).getPath() + File.pathSeparator;
130                        if (metainf) {
131                                return prefix(path + MetaInfUtils.METAINF_DIRECTORY_NAME + File.pathSeparator);
132                        } else {
133                                return prefix(path);
134                        }
135                }
136
137                /**
138                 * Typically {@code classpath:}
139                 */
140                public Builder prefix(String prefix) {
141                        this.prefix = prefix;
142                        return this;
143                }
144
145                public ProjectResource build() {
146                        ProjectResource instance = new ProjectResource(this);
147                        validate(instance);
148                        return instance;
149                }
150
151                private static void validate(ProjectResource instance) {
152                        checkNotNull(instance.project, "'project' cannot be null");
153                        checkArgument(!StringUtils.isBlank(instance.path), "'path' cannot be blank");
154                        checkArgument(!StringUtils.isBlank(instance.prefix), "'prefix' cannot be blank");
155                }
156        }
157
158        public ProjectIdentifier getProject() {
159                return project;
160        }
161
162        public String getPrefix() {
163                return prefix;
164        }
165
166        public String getPath() {
167                return path;
168        }
169
170}