/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.sync.engine.util;
import ch.securityvision.xattrj.Xattrj;
import com.liferay.sync.engine.model.SyncFile;
import com.liferay.sync.engine.service.SyncFileService;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.UserDefinedFileAttributeView;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Shinn Lok
*/
public class FileKeyUtil {
public static long getFileKey(Path filePath) {
if (!FileUtil.isRealFilePath(filePath) || !FileUtil.exists(filePath)) {
return -1;
}
try {
if (OSDetector.isApple()) {
Xattrj xattrj = getXattrj();
if (xattrj == null) {
return -1;
}
String fileKey = xattrj.readAttribute(
filePath.toFile(), "fileKey");
if (fileKey == null) {
return -1;
}
return Long.parseLong(fileKey);
}
else {
UserDefinedFileAttributeView userDefinedFileAttributeView =
Files.getFileAttributeView(
filePath, UserDefinedFileAttributeView.class);
List<String> list = userDefinedFileAttributeView.list();
if (!list.contains("fileKey")) {
return -1;
}
ByteBuffer byteBuffer = ByteBuffer.allocate(20);
userDefinedFileAttributeView.read("fileKey", byteBuffer);
CharBuffer charBuffer = _CHARSET.decode(
(ByteBuffer)byteBuffer.flip());
return Long.parseLong(charBuffer.toString());
}
}
catch (Exception e) {
_logger.error(e.getMessage(), e);
return -1;
}
}
public static boolean hasFileKey(Path filePath, long fileKey) {
if (getFileKey(filePath) == fileKey) {
return true;
}
return false;
}
public static void writeFileKey(
final Path filePath, final String fileKey, boolean acquireFileLock) {
if (hasFileKey(filePath, Long.parseLong(fileKey))) {
return;
}
if (!acquireFileLock) {
doWriteFileKey(filePath, fileKey);
return;
}
PathCallable pathCallable = new PathCallable(filePath) {
@Override
public Object call() throws Exception {
doWriteFileKey(filePath, fileKey);
return null;
}
};
FileLockRetryUtil.registerPathCallable(pathCallable);
}
public static void writeFileKeys(final Path filePath) throws IOException {
Files.walkFileTree(
filePath,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(
Path filePath, BasicFileAttributes basicFileAttributes)
throws IOException {
SyncFile syncFile = SyncFileService.fetchSyncFile(
filePath.toString());
if (syncFile == null) {
return FileVisitResult.SKIP_SUBTREE;
}
doWriteFileKey(
filePath, String.valueOf(syncFile.getSyncFileId()));
return super.preVisitDirectory(
filePath, basicFileAttributes);
}
@Override
public FileVisitResult visitFile(
Path filePath, BasicFileAttributes basicFileAttributes)
throws IOException {
SyncFile syncFile = SyncFileService.fetchSyncFile(
filePath.toString());
if (syncFile != null) {
doWriteFileKey(
filePath, String.valueOf(syncFile.getSyncFileId()));
}
return FileVisitResult.CONTINUE;
}
});
}
protected static void doWriteFileKey(Path filePath, String fileKey) {
if (hasFileKey(filePath, Long.parseLong(fileKey))) {
return;
}
if (OSDetector.isApple()) {
Xattrj xattrj = getXattrj();
if (xattrj == null) {
return;
}
File file = filePath.toFile();
if (!file.canWrite()) {
file.setWritable(true);
}
xattrj.writeAttribute(file, "fileKey", fileKey);
}
else {
File file = filePath.toFile();
if (!file.canWrite()) {
file.setWritable(true);
}
UserDefinedFileAttributeView userDefinedFileAttributeView =
Files.getFileAttributeView(
filePath, UserDefinedFileAttributeView.class);
try {
userDefinedFileAttributeView.write(
"fileKey", _CHARSET.encode(CharBuffer.wrap(fileKey)));
}
catch (Exception e) {
_logger.error(e.getMessage(), e);
}
}
}
protected static Xattrj getXattrj() {
if (_xattrj != null) {
return _xattrj;
}
try {
_xattrj = new Xattrj();
return _xattrj;
}
catch (IOException ioe) {
_logger.error(ioe.getMessage(), ioe);
return null;
}
}
private static final Charset _CHARSET = Charset.forName("UTF-8");
private static final Logger _logger = LoggerFactory.getLogger(
FileKeyUtil.class);
private static Xattrj _xattrj;
}