summaryrefslogtreecommitdiffstats
path: root/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java
diff options
context:
space:
mode:
Diffstat (limited to 'config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java')
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java200
1 files changed, 200 insertions, 0 deletions
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java
new file mode 100644
index 00000000000..67a180d334d
--- /dev/null
+++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationFile.java
@@ -0,0 +1,200 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.config.model.application.provider;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.yahoo.config.application.api.ApplicationFile;
+import com.yahoo.io.IOUtils;
+import com.yahoo.path.Path;
+import com.yahoo.log.LogLevel;
+import com.yahoo.yolean.Exceptions;
+import com.yahoo.vespa.config.util.ConfigUtils;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * @author lulf
+ * @author vegardh
+ * @since 5.1
+ */
+public class FilesApplicationFile extends ApplicationFile {
+ private static final Logger log = Logger.getLogger("FilesApplicationFile");
+ private final File file;
+ private final ObjectMapper mapper = new ObjectMapper();
+ public FilesApplicationFile(Path path, File file) {
+ super(path);
+ this.file = file;
+ }
+
+ @Override
+ public boolean isDirectory() {
+ return file.isDirectory();
+ }
+
+ @Override
+ public boolean exists() {
+ return file.exists();
+ }
+
+ @Override
+ public ApplicationFile delete() {
+ log.log(LogLevel.DEBUG, "Delete " + file);
+ if (file.isDirectory() && !listFiles().isEmpty()) {
+ throw new RuntimeException("files. Can't delete, directory not empty: " + this + "(" + listFiles() + ")." + listFiles().size());
+ }
+ if (file.isDirectory() && file.listFiles() != null && file.listFiles().length > 0) {
+ for (File f : file.listFiles()) {
+ deleteFile(f);
+ }
+ }
+ if (!file.delete()) {
+ throw new IllegalStateException("Unable to delete: "+this);
+ }
+ try {
+ writeMetaFile("", ApplicationFile.ContentStatusDeleted);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+
+
+ public static boolean deleteFile(File path) {
+ if( path.exists() ) {
+ if (path.isDirectory()) {
+ File[] files = path.listFiles();
+ for(int i=0; i<files.length; i++) {
+ if(files[i].isDirectory()) {
+ deleteFile(files[i]);
+ } else {
+ files[i].delete();
+ }
+ }
+ }
+ }
+ return(path.delete());
+ }
+
+ @Override
+ public Reader createReader() throws FileNotFoundException {
+ return new FileReader(file);
+ }
+
+ @Override
+ public InputStream createInputStream() throws FileNotFoundException {
+ return new FileInputStream(file);
+ }
+
+ @Override
+ public ApplicationFile createDirectory() {
+ if (file.isDirectory()) return this;
+ if (file.exists()) {
+ throw new IllegalArgumentException("Unable to create directory, file exists: "+file);
+ }
+ if (!file.mkdirs()) {
+ throw new IllegalArgumentException("Unable to create directory: "+file);
+ }
+ try {
+ writeMetaFile("", ApplicationFile.ContentStatusNew);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+
+ @Override
+ public ApplicationFile writeFile(Reader input) {
+ if (file.getParentFile() != null) {
+ file.getParentFile().mkdirs();
+ }
+ try {
+ String data = com.yahoo.io.IOUtils.readAll(input);
+ String status = file.exists() ? ApplicationFile.ContentStatusChanged : ApplicationFile.ContentStatusNew;
+ IOUtils.writeFile(file, data, false);
+ writeMetaFile(data, status);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+
+ @Override
+ public List<ApplicationFile> listFiles(final PathFilter filter) {
+ List<ApplicationFile> files = new ArrayList<>();
+ if (!file.isDirectory()) {
+ return files;
+ }
+ FileFilter fileFilter = pathname -> filter.accept(path.append(pathname.getName()));
+ for (File child : file.listFiles(fileFilter)) {
+ // Ignore dot-files.
+ if (!child.getName().startsWith(".")) {
+ files.add(new FilesApplicationFile(path.append(child.getName()), child));
+ }
+ }
+ return files;
+ }
+
+ private void writeMetaFile(String data, String status) throws IOException {
+ File metaDir = createMetaDir();
+ log.log(LogLevel.DEBUG, "meta dir=" + metaDir);
+ File metaFile = new File(metaDir + "/" + getPath().getName());
+ if (status == null) {
+ status = ApplicationFile.ContentStatusNew;
+ if (metaFile.exists()) {
+ status = ApplicationFile.ContentStatusChanged;
+ }
+ }
+ String hash;
+ if (file.isDirectory() || status.equals(ApplicationFile.ContentStatusDeleted)) {
+ hash = "";
+ } else {
+ hash = ConfigUtils.getMd5(data);
+ }
+ mapper.writeValue(metaFile, new MetaData(status, hash));
+ }
+
+ private File createMetaDir() {
+ File metaDir = getMetaDir();
+ if (!metaDir.exists()) {
+ log.log(LogLevel.DEBUG, "Creating meta dir " + metaDir);
+ metaDir.mkdirs();
+ }
+ return metaDir;
+ }
+
+ private File getMetaDir() {
+ String substring = file.getAbsolutePath().substring(0, file.getAbsolutePath().lastIndexOf("/") + 1);
+ return new File(substring + Path.fromString(".meta/"));
+ }
+
+ public MetaData getMetaData() {
+ File metaDir = getMetaDir();
+ File metaFile = new File(metaDir + "/" + getPath().getName());
+ log.log(LogLevel.DEBUG, "Getting metadata for " + metaFile);
+ if (metaFile.exists()) {
+ try {
+ return mapper.readValue(metaFile, MetaData.class);
+ } catch (IOException e) {
+ System.out.println("whot:" + Exceptions.toMessageString(e));
+ // return below
+ }
+ }
+ try {
+ if (file.isDirectory()) {
+ return new MetaData(ApplicationFile.ContentStatusNew, "");
+ } else {
+ return new MetaData(ApplicationFile.ContentStatusNew, ConfigUtils.getMd5(IOUtils.readAll(createReader())));
+ }
+ } catch (IOException | IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public int compareTo(ApplicationFile other) {
+ if (other == this) return 0;
+ return this.getPath().getName().compareTo((other).getPath().getName());
+ }
+}