001/*
002 *  Copyright 2020 Anyware Services
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 */
016package org.ametys.core.util.path;
017
018import java.io.IOException;
019import java.nio.file.Files;
020import java.nio.file.Path;
021
022import org.apache.commons.lang3.StringUtils;
023import org.apache.excalibur.source.SourceValidity;
024
025import org.ametys.core.util.JarFSManager;
026
027/**
028 * A validation object for time-stamps.
029 */
030public class PathTimeStampValidity implements SourceValidity
031{
032    /** The timestamp */
033    protected long _timeStamp;
034    private transient Path _file;
035    private String _absolutePath;
036
037    /**
038     * Creates from a name
039     * @param filename File name
040     */
041    public PathTimeStampValidity(final String filename)
042    {
043        this(Path.of(filename));
044    }
045
046    /**
047     * Creates from a file
048     * @param file file wrapped
049     */
050    public PathTimeStampValidity(final Path file)
051    {
052        this(file, _getTimeStamp(file));
053    }
054
055    /**
056     * Creates from a file
057     * @param file file wrapped
058     * @param timeStamp file timestamp
059     */
060    public PathTimeStampValidity(final Path file, final long timeStamp)
061    {
062        _file = file;
063        _absolutePath = StringUtils.substringAfter(file.toUri().toString(), "file:");
064        _timeStamp = timeStamp;
065    }
066    
067    /**
068     * Empty constructor for sub classes only.
069     */
070    protected PathTimeStampValidity()
071    {
072        // Nothing
073    }
074
075    /**
076     * Get the timestamp from a file
077     * @param file the file
078     * @return the file's timestamp
079     */
080    protected static long _getTimeStamp(Path file)
081    {
082        try
083        {
084            return Files.getLastModifiedTime(file).toMillis();
085        }
086        catch (IOException e)
087        {
088            return -1;
089        }
090    }
091    
092    public int isValid()
093    {
094        return _getTimeStamp(getFile()) == _timeStamp ? 1 : -1;
095    }
096
097    public int isValid(final SourceValidity newValidity)
098    {
099        if (newValidity instanceof PathTimeStampValidity)
100        {
101            final long timeStamp = ((PathTimeStampValidity) newValidity).getTimeStamp();
102            return _timeStamp == timeStamp ? 1 : -1;
103        }
104        return -1;
105    }
106
107    /**
108     * Get the file
109     * @return the file
110     */
111    public Path getFile()
112    {
113        if (_file == null)
114        {
115            _file = _getFile(_absolutePath);
116        }
117        
118        return this._file;
119    }
120    
121    /**
122     * Get file from an absolute path
123     * @param absolutePath the absolute path
124     * @return the file
125     */
126    protected static Path _getFile(String absolutePath)
127    {
128        String[] path = StringUtils.split(absolutePath, "!");
129        if (path.length == 2)
130        {
131            try
132            {
133                return JarFSManager.getInstance().getFileSystemByFile(new java.io.File(path[0])).getPath(path[1]);
134            }
135            catch (IOException e)
136            {
137                throw new RuntimeException("Cannot unserialize the path " + absolutePath, e);
138            }
139        }
140        else
141        {
142            return new java.io.File(path[0]).toPath();
143        }
144    }
145
146    /**
147     * Get the timestamp
148     * @return the timestamp or -1 if it cannot be computed
149     */
150    public long getTimeStamp()
151    {
152        return this._timeStamp;
153    }
154
155    @Override
156    public String toString()
157    {
158        return "FileTimeStampValidity: " + getFile().toString() + ": " + this._timeStamp;
159    }
160
161}