001/*
002 * Copyright 2012-2018 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.devtools.filewatch;
018
019import java.io.File;
020
021import org.springframework.util.Assert;
022import org.springframework.util.StringUtils;
023
024/**
025 * A single file that has changed.
026 *
027 * @author Phillip Webb
028 * @since 1.3.0
029 * @see ChangedFiles
030 */
031public final class ChangedFile {
032
033        private final File sourceFolder;
034
035        private final File file;
036
037        private final Type type;
038
039        /**
040         * Create a new {@link ChangedFile} instance.
041         * @param sourceFolder the source folder
042         * @param file the file
043         * @param type the type of change
044         */
045        public ChangedFile(File sourceFolder, File file, Type type) {
046                Assert.notNull(sourceFolder, "SourceFolder must not be null");
047                Assert.notNull(file, "File must not be null");
048                Assert.notNull(type, "Type must not be null");
049                this.sourceFolder = sourceFolder;
050                this.file = file;
051                this.type = type;
052        }
053
054        /**
055         * Return the file that was changed.
056         * @return the file
057         */
058        public File getFile() {
059                return this.file;
060        }
061
062        /**
063         * Return the type of change.
064         * @return the type of change
065         */
066        public Type getType() {
067                return this.type;
068        }
069
070        /**
071         * Return the name of the file relative to the source folder.
072         * @return the relative name
073         */
074        public String getRelativeName() {
075                File folder = this.sourceFolder.getAbsoluteFile();
076                File file = this.file.getAbsoluteFile();
077                String folderName = StringUtils.cleanPath(folder.getPath());
078                String fileName = StringUtils.cleanPath(file.getPath());
079                Assert.state(fileName.startsWith(folderName), () -> "The file " + fileName
080                                + " is not contained in the source folder " + folderName);
081                return fileName.substring(folderName.length() + 1);
082        }
083
084        @Override
085        public boolean equals(Object obj) {
086                if (obj == this) {
087                        return true;
088                }
089                if (obj == null) {
090                        return false;
091                }
092                if (obj instanceof ChangedFile) {
093                        ChangedFile other = (ChangedFile) obj;
094                        return this.file.equals(other.file) && this.type.equals(other.type);
095                }
096                return super.equals(obj);
097        }
098
099        @Override
100        public int hashCode() {
101                return this.file.hashCode() * 31 + this.type.hashCode();
102        }
103
104        @Override
105        public String toString() {
106                return this.file + " (" + this.type + ")";
107        }
108
109        /**
110         * Change types.
111         */
112        public enum Type {
113
114                /**
115                 * A new file has been added.
116                 */
117                ADD,
118
119                /**
120                 * An existing file has been modified.
121                 */
122                MODIFY,
123
124                /**
125                 * An existing file has been deleted.
126                 */
127                DELETE
128
129        }
130
131}