Skip to content
Snippets Groups Projects
Commit ef16867e authored by Wei Liu's avatar Wei Liu
Browse files

use iterator instead of cursor to work around the bug in asset.query

parent 66477a83
Branches
Tags
No related merge requests found
......@@ -5,7 +5,7 @@
<groupId>au.edu.unimelb.mf</groupId>
<artifactId>unimelb-mf-clients</artifactId>
<version>0.7.7</version>
<version>0.7.8</version>
<packaging>jar</packaging>
<name>unimelb-mf-clients</name>
<url>https://gitlab.unimelb.edu.au/resplat-mediaflux/unimelb-mf-clients
......
......@@ -878,7 +878,7 @@ public abstract class MFSyncApp extends AbstractMFApp<unimelb.mf.client.sync.set
}
}
private void syncDeleteAssets() {
private void syncDeleteAssets() throws Throwable {
List<Job> jobs = settings().jobs();
for (Job job : jobs) {
if (job instanceof DirectoryUploadJob) {
......
......@@ -17,22 +17,26 @@ import unimelb.mf.client.sync.settings.downstream.DownJob;
import unimelb.mf.client.sync.settings.upstream.DirectoryUploadJob;
import unimelb.mf.client.task.AbstractMFTask;
import unimelb.mf.client.util.AssetNamespaceUtils;
import unimelb.mf.client.util.AssetQueryUtils;
import unimelb.mf.client.util.AssetUtils;
import unimelb.utils.PathUtils;
public class SyncDeleteAssetsTask extends AbstractMFTask {
private final Path _dir;
private final String _ns;
private final Path _srcDir;
private final String _dstDirPath;
private final boolean _dstDirIsNamespace;
private final boolean _hardDestroy;
private final int _batchSize;
private final boolean _verbose;
private final AtomicInteger _counter;
public SyncDeleteAssetsTask(MFSession session, Logger logger, Path dir, String ns, boolean hardDestroy,
int batchSize, boolean verbose, AtomicInteger counter) {
public SyncDeleteAssetsTask(MFSession session, Logger logger, Path srcDir, String dstDir, boolean dstDirIsNamespace,
boolean hardDestroy, int batchSize, boolean verbose, AtomicInteger counter) {
super(session, logger);
_dir = dir;
_ns = ns;
_srcDir = srcDir;
_dstDirPath = dstDir;
_dstDirIsNamespace = dstDirIsNamespace;
_hardDestroy = hardDestroy;
_batchSize = batchSize;
_verbose = verbose;
......@@ -40,58 +44,70 @@ public class SyncDeleteAssetsTask extends AbstractMFTask {
}
public SyncDeleteAssetsTask(MFSession session, Logger logger, DirectoryUploadJob job, Settings settings,
AtomicInteger counter) {
this(session, logger, job.srcDirectory(), job.dstCollection().path(), settings.hardDestroyAssets(),
AtomicInteger counter) throws Throwable {
this(session, logger, job.srcDirectory(), job.dstCollection().path(),
job.dstCollection().resolve(session).isAssetNamespace(), settings.hardDestroyAssets(),
settings.batchSize(), settings.verbose(), counter);
}
@Override
public void execute() throws Throwable {
if (_verbose) {
logger().info("Checking namespace: '" + _ns + "' Looking for assets to delete...");
logger().info("Checking assets in directory: '" + _dstDirPath + "'... looking for assets to delete...");
}
processAssets();
processEmptyAssetNamespaces();
if (_dstDirIsNamespace) {
processEmptyAssetNamespaces();
} else {
processEmptyCollections();
}
}
private void processAssets() throws Throwable {
long idx = 1;
XmlStringWriter w = new XmlStringWriter();
if (_dstDirIsNamespace) {
w.add("namespace", _dstDirPath);
} else {
w.add("collection", "path=" + _dstDirPath);
}
w.add("where", "(asset has content or asset has link) and not(asset is collection)");
w.add("as", "iterator");
w.add("action", "get-path");
String iteratorId = session().execute("asset.query", w.document()).value("iterator");
String args = String.format("<id>%s</id><size>%d</size>", iteratorId, _batchSize);
boolean complete = false;
while (!complete && !Thread.interrupted()) {
XmlStringWriter w = new XmlStringWriter();
w.add("namespace", _ns);
w.add("where", "asset has content or asset has link");
w.add("action", "get-path");
w.add("size", _batchSize);
w.add("idx", idx);
XmlDoc.Element re = session().execute("asset.query", w.document());
List<XmlDoc.Element> pes = re.elements("path");
if (pes != null && !pes.isEmpty()) {
Set<String> toDestroy = new LinkedHashSet<>();
for (XmlDoc.Element pe : pes) {
String assetPath = pe.value();
String assetId = pe.value("@id");
Path file = DownJob.dstFilePath(_dir, _ns, assetPath);
if (!Files.exists(file)) {
toDestroy.add(assetId);
if (_verbose) {
logger().info("Submitted asset: '" + assetPath + "' to destroy");
try {
while (!complete && !Thread.interrupted()) {
XmlDoc.Element re = session().execute("asset.query.iterate", args);
complete = re.booleanValue("iterated/@complete");
List<XmlDoc.Element> pes = re.elements("path");
if (pes != null && !pes.isEmpty()) {
Set<String> toDestroy = new LinkedHashSet<>();
for (XmlDoc.Element pe : pes) {
String assetPath = pe.value();
String assetId = pe.value("@id");
Path file = DownJob.dstFilePath(_srcDir, _dstDirPath, assetPath);
if (!Files.exists(file)) {
toDestroy.add(assetId);
if (_verbose) {
logger().info("Submitted asset: '" + assetPath + "' to destroy");
}
}
}
}
if (!toDestroy.isEmpty()) {
destroyAssets(toDestroy);
if (_counter != null) {
_counter.getAndAdd(toDestroy.size());
}
if (_verbose) {
logger().info("Deleted " + toDestroy.size() + " assets...");
if (!toDestroy.isEmpty()) {
destroyAssets(toDestroy);
if (_counter != null) {
_counter.getAndAdd(toDestroy.size());
}
if (_verbose) {
logger().info(
"Deleted " + toDestroy.size() + " asset" + (toDestroy.size() == 1 ? "." : "s."));
}
}
idx -= toDestroy.size();
}
}
idx += _batchSize;
complete = re.booleanValue("cursor/total/@complete");
} finally {
AssetQueryUtils.destroyIterator(session(), iteratorId, true);
}
}
......@@ -105,57 +121,127 @@ public class SyncDeleteAssetsTask extends AbstractMFTask {
session().execute(service, w1.document());
}
private void processEmptyCollections() throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("collection", "path=" + _dstDirPath);
w.add("where", "asset collection member count=0");
w.add("as", "iterator");
w.add("action", "get-path");
String iteratorId = session().execute("asset.query", w.document()).value("iterator");
String args = String.format("<id>%s</id><size>%d</size>", iteratorId, _batchSize);
boolean complete = false;
try {
while (!complete && !Thread.interrupted()) {
XmlDoc.Element re = session().execute("asset.query.iterate", args);
complete = re.booleanValue("iterated/@complete");
List<XmlDoc.Element> pes = re.elements("path");
if (pes != null && !pes.isEmpty()) {
for (XmlDoc.Element pe : pes) {
String collectionAssetPath = pe.value();
processEmptyCollection(collectionAssetPath, false);
}
}
}
} finally {
AssetQueryUtils.destroyIterator(session(), iteratorId, true);
}
}
private void processEmptyCollection(String collectionAssetPath, boolean checkIfEmpty) throws Throwable {
if (!collectionAssetPath.startsWith(_dstDirPath + "/")) {
// root collection should not be destroyed even if it's empty
return;
}
Path dir = DownJob.dstFilePath(_srcDir, _dstDirPath, collectionAssetPath);
if (Files.isDirectory(dir)) {
// local directory exists. should not be destroyed
return;
}
if (!AssetUtils.assetExists(collectionAssetPath, session())) {
// collection no longer exists
return;
}
if (checkIfEmpty) {
if (!AssetUtils.isEmptyCollectionAsset(collectionAssetPath, session())) {
// collection is not empty
return;
}
}
try {
AssetUtils.destroyAsset(collectionAssetPath, session(), false, _hardDestroy);
if (_verbose) {
logger().info("Deleted empty asset namespace: '" + collectionAssetPath + "'");
}
String parentPath = PathUtils.getParentPath(collectionAssetPath);
if (AssetUtils.assetExists(parentPath, session())) {
processEmptyCollection(parentPath, true);
}
} catch (Throwable e) {
logger().warning(
"Failed to destory asset namespace: '" + collectionAssetPath + "'. " + "Error: " + e.getMessage());
}
}
private void processEmptyAssetNamespaces() throws Throwable {
long idx = 0;
boolean complete = false;
while (!complete && !Thread.interrupted()) {
XmlStringWriter w = new XmlStringWriter();
w.add("namespace", _ns);
w.add("namespace", _dstDirPath);
w.add("leaf-only", true);
w.add("idx", idx);
w.add("size", _batchSize);
XmlDoc.Element re = session().execute("asset.namespace.empty.list", w.document());
idx += _batchSize;
Collection<String> nss = re.values("namespace");
if (nss != null && !nss.isEmpty()) {
for (String ns : nss) {
processEmptyAssetNamespace(ns, false);
Collection<String> namespaces = re.values("namespace");
complete = namespaces == null || namespaces.isEmpty();
if (!complete) {
for (String namespacePath : namespaces) {
boolean destroyed = processEmptyAssetNamespace(namespacePath, false);
if (destroyed) {
// move the cursor back one so that it will not miss the namespace(s) in the
// next page
idx -= 1;
}
}
} else {
complete = true;
}
}
}
private void processEmptyAssetNamespace(String ns, boolean checkIfEmpty) throws Throwable {
if (!ns.startsWith(_ns + "/")) {
private boolean processEmptyAssetNamespace(String namespacePath, boolean checkIfEmpty) throws Throwable {
if (!namespacePath.startsWith(_dstDirPath + "/")) {
// root namespace should not be destroyed even if it's empty
return;
return false;
}
Path dir = DownJob.dstFilePath(_dir, _ns, ns);
Path dir = DownJob.dstFilePath(_srcDir, _dstDirPath, namespacePath);
if (Files.isDirectory(dir)) {
// local directory does not exist
return;
// corresponding local directory exists. should not be destroyed
return false;
}
if (!AssetNamespaceUtils.assetNamespaceExists(session(), ns)) {
// namespace no longer exists
return;
if (!AssetNamespaceUtils.assetNamespaceExists(session(), namespacePath)) {
// asset namespace no longer exists
return true;
}
if (checkIfEmpty) {
if (!AssetNamespaceUtils.isEmpty(session(), ns)) {
// namespace is not empty
return;
if (!AssetNamespaceUtils.isEmpty(session(), namespacePath)) {
// asset namespace is not empty
return false;
}
}
boolean destroyed = false;
try {
AssetNamespaceUtils.destroyAssetNamespace(session(), ns);
AssetNamespaceUtils.destroyAssetNamespace(session(), namespacePath);
destroyed = true;
if (_verbose) {
logger().info("Deleted empty asset namespace: '" + ns + "'");
logger().info("Deleted empty asset namespace: '" + namespacePath + "'");
}
} catch (Throwable e) {
logger().warning("Failed to destory asset namespace: '" + ns + "'. " + "Error: " + e.getMessage());
logger().warning(
"Failed to destory asset namespace: '" + namespacePath + "'. " + "Error: " + e.getMessage());
destroyed = false;
}
String pns = PathUtils.getParentPath(ns);
String pns = PathUtils.getParentPath(namespacePath);
processEmptyAssetNamespace(pns, true);
return destroyed;
}
}
......@@ -2,6 +2,7 @@ package unimelb.mf.client.util;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Objects;
import arc.mf.client.ServerClient;
import arc.xml.XmlDoc;
......@@ -12,197 +13,225 @@ import unimelb.mf.client.util.collection.CollectionType;
public class AssetUtils {
public static XmlDoc.Element getAssetMeta(ServerClient.Connection connection, String assetId) throws Throwable {
return getAssetMeta(connection, assetId, null, false);
}
public static XmlDoc.Element getAssetMeta(ServerClient.Connection connection, String assetId, String cid)
throws Throwable {
return getAssetMeta(connection, assetId, cid, false);
}
public static XmlDoc.Element getAssetMetaByCID(ServerClient.Connection connection, String cid) throws Throwable {
return getAssetMeta(connection, null, cid, false);
}
public static XmlDoc.Element getAssetMeta(ServerClient.Connection connection, String assetId, String cid,
boolean lock) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
if (assetId != null) {
w.add("id", assetId);
} else if (cid != null) {
w.add("cid", cid);
} else {
throw new IllegalArgumentException("Missing asset identifiers.");
}
if (lock) {
w.add("lock", true);
}
return connection.execute("asset.get", w.document()).element("asset");
}
public static XmlDoc.Element getAssetMeta(MFSession session, String assetId) throws Throwable {
return getAssetMeta(session, assetId, null, false);
}
public static XmlDoc.Element getAssetMetaByPath(MFSession session, String assetPath) throws Throwable {
return getAssetMeta(session, "path=" + assetPath, null, false);
}
public static XmlDoc.Element getAssetMetaByCID(MFSession session, String cid) throws Throwable {
return getAssetMeta(session, null, cid, false);
}
public static List<XmlDoc.Element> getAssetMetaByCIDs(MFSession session, String... cids) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
for (String cid : cids) {
w.push("service", new String[] { "name", "asset.get" });
w.add("cid", cid);
w.pop();
}
return session.execute("service.execute", w.document()).elements("reply/response/asset");
}
public static XmlDoc.Element getAssetMeta(MFSession session, String assetId, String cid, boolean lock)
throws Throwable {
XmlStringWriter w = new XmlStringWriter();
if (assetId != null) {
w.add("id", assetId);
} else if (cid != null) {
w.add("cid", cid);
} else {
throw new IllegalArgumentException("Missing asset identifiers.");
}
if (lock) {
w.add("lock", true);
}
return session.execute("asset.get", w.document()).element("asset");
}
public static void lockAsset(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
session.execute("asset.lock", w.document());
}
public static void unlockAsset(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
session.execute("asset.unlock", w.document());
}
public static void unlockAsset(String assetPath, MFSession session) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", "path=" + assetPath);
session.execute("asset.unlock", w.document());
}
public static void unlockAssetByCID(MFSession session, String cid) throws Throwable {
unlockAsset(session, idFromCID(session, cid));
}
public static String idFromCID(MFSession session, String cid) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("cid", cid);
return session.execute("asset.identifier.get", w.document()).value("id");
}
public static String cidFromID(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
return session.execute("asset.identifier.get", w.document()).value("id/@cid");
}
public static void unlockAsset(MFSession session, HasID id) throws Throwable {
if (id.assetId() != null) {
unlockAsset(session, id.assetId());
} else if (id.citeableId() != null) {
unlockAssetByCID(session, id.citeableId());
} else if (id.path() != null) {
unlockAsset(id.path(), session);
} else {
throw new IllegalArgumentException("Missing asset identifier.");
}
}
public static boolean assetExists(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
return session.execute("asset.exists", w.document()).booleanValue("exists");
}
public static boolean assetExists(String assetPath, MFSession session) throws Throwable {
return assetExists(session, "path=" + assetPath);
}
public static void setWorm(MFSession session, String assetId, boolean canAddVersions, boolean canMove)
throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
w.add("can-add-versions", canAddVersions);
w.add("can-move", canMove);
session.execute("asset.worm.set", w.document());
}
public static String getCollectionStore(MFSession session, String collectionAssetId) throws Throwable {
XmlDoc.Element ae = getAssetMeta(session, collectionAssetId);
return ae.value("collection/store");
}
public static String getCollectionStore(String collectionAssetPath, MFSession session) throws Throwable {
return getCollectionStore(session, "path=" + collectionAssetPath);
}
public static boolean collectionAssetExists(String path, MFSession session) throws Throwable {
if (assetExists(path, session)) {
XmlDoc.Element ae = getAssetMetaByPath(session, path);
return ae.elementExists("collection");
}
return false;
}
public static String createCollectionAsset(MFSession session, String assetPath, boolean createParents,
boolean ignoreIfExists) throws Throwable {
if (ignoreIfExists) {
if (assetExists(assetPath, session)) {
XmlDoc.Element ae = getAssetMetaByPath(session, assetPath);
boolean isCollection = ae.elementExists("collection");
if (isCollection) {
return ae.value("@id");
}
}
}
XmlStringWriter w = new XmlStringWriter();
String parentPath = AssetPathUtils.getParent(assetPath);
CollectionType parentType = CollectionType.collectionTypeOf(parentPath, session);
if (parentType == null) {
if (!createParents) {
// parent does not exist and not creating it
throw new FileNotFoundException("parent collection: '" + parentPath + "' does not exist.");
} else {
parentType = CollectionType.collectionTypeFor(parentPath, session);
}
}
if (parentType == CollectionType.COLLECTION_ASSET) {
w.add("pid", new String[] { "create", Boolean.toString(createParents) }, "path=" + parentPath);
} else {
w.add("namespace", new String[] { "create", Boolean.toString(createParents) }, parentPath);
}
w.add("name", AssetPathUtils.getName(assetPath));
boolean levelZeroRoot = "/".equals(parentPath);
w.add("collection",
new String[] { "unique-name-index", "true", "level-zero-root", Boolean.toString(levelZeroRoot) }, true);
XmlDoc.Element ae = session.execute("asset.create", w.document());
return ae.value("id");
}
public static long countFileAssetsInCollection(String collectionAssetPath, MFSession session) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("collection", "path=" + collectionAssetPath);
w.add("where", "(asset has content or asset has link) and not(asset is collection)");
return session.execute("asset.count", w.document()).longValue("total");
}
public static XmlDoc.Element getAssetMeta(ServerClient.Connection connection, String assetId) throws Throwable {
return getAssetMeta(connection, assetId, null, false);
}
public static XmlDoc.Element getAssetMeta(ServerClient.Connection connection, String assetId, String cid)
throws Throwable {
return getAssetMeta(connection, assetId, cid, false);
}
public static XmlDoc.Element getAssetMetaByCID(ServerClient.Connection connection, String cid) throws Throwable {
return getAssetMeta(connection, null, cid, false);
}
public static XmlDoc.Element getAssetMeta(ServerClient.Connection connection, String assetId, String cid,
boolean lock) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
if (assetId != null) {
w.add("id", assetId);
} else if (cid != null) {
w.add("cid", cid);
} else {
throw new IllegalArgumentException("Missing asset identifiers.");
}
if (lock) {
w.add("lock", true);
}
return connection.execute("asset.get", w.document()).element("asset");
}
public static XmlDoc.Element getAssetMeta(MFSession session, String assetId) throws Throwable {
return getAssetMeta(session, assetId, null, false);
}
public static XmlDoc.Element getAssetMetaByPath(MFSession session, String assetPath) throws Throwable {
return getAssetMeta(session, "path=" + assetPath, null, false);
}
public static XmlDoc.Element getAssetMetaByCID(MFSession session, String cid) throws Throwable {
return getAssetMeta(session, null, cid, false);
}
public static List<XmlDoc.Element> getAssetMetaByCIDs(MFSession session, String... cids) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
for (String cid : cids) {
w.push("service", new String[] { "name", "asset.get" });
w.add("cid", cid);
w.pop();
}
return session.execute("service.execute", w.document()).elements("reply/response/asset");
}
public static XmlDoc.Element getAssetMeta(MFSession session, String assetId, String cid, boolean lock)
throws Throwable {
XmlStringWriter w = new XmlStringWriter();
if (assetId != null) {
w.add("id", assetId);
} else if (cid != null) {
w.add("cid", cid);
} else {
throw new IllegalArgumentException("Missing asset identifiers.");
}
if (lock) {
w.add("lock", true);
}
return session.execute("asset.get", w.document()).element("asset");
}
public static void lockAsset(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
session.execute("asset.lock", w.document());
}
public static void unlockAsset(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
session.execute("asset.unlock", w.document());
}
public static void unlockAsset(String assetPath, MFSession session) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", "path=" + assetPath);
session.execute("asset.unlock", w.document());
}
public static void unlockAssetByCID(MFSession session, String cid) throws Throwable {
unlockAsset(session, idFromCID(session, cid));
}
public static String idFromCID(MFSession session, String cid) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("cid", cid);
return session.execute("asset.identifier.get", w.document()).value("id");
}
public static String cidFromID(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
return session.execute("asset.identifier.get", w.document()).value("id/@cid");
}
public static String idFromPath(String assetPath, MFSession session) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", "path=" + assetPath);
return session.execute("asset.identifier.get", w.document()).value("id");
}
public static void unlockAsset(MFSession session, HasID id) throws Throwable {
if (id.assetId() != null) {
unlockAsset(session, id.assetId());
} else if (id.citeableId() != null) {
unlockAssetByCID(session, id.citeableId());
} else if (id.path() != null) {
unlockAsset(id.path(), session);
} else {
throw new IllegalArgumentException("Missing asset identifier.");
}
}
public static boolean assetExists(MFSession session, String assetId) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
return session.execute("asset.exists", w.document()).booleanValue("exists");
}
public static boolean assetExists(String assetPath, MFSession session) throws Throwable {
return assetExists(session, "path=" + assetPath);
}
public static void setWorm(MFSession session, String assetId, boolean canAddVersions, boolean canMove)
throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
w.add("can-add-versions", canAddVersions);
w.add("can-move", canMove);
session.execute("asset.worm.set", w.document());
}
public static String getCollectionStore(MFSession session, String collectionAssetId) throws Throwable {
XmlDoc.Element ae = getAssetMeta(session, collectionAssetId);
return ae.value("collection/store");
}
public static String getCollectionStore(String collectionAssetPath, MFSession session) throws Throwable {
return getCollectionStore(session, "path=" + collectionAssetPath);
}
public static boolean collectionAssetExists(String path, MFSession session) throws Throwable {
if (assetExists(path, session)) {
XmlDoc.Element ae = getAssetMetaByPath(session, path);
return ae.elementExists("collection");
}
return false;
}
public static String createCollectionAsset(MFSession session, String assetPath, boolean createParents,
boolean ignoreIfExists) throws Throwable {
if (ignoreIfExists) {
if (assetExists(assetPath, session)) {
XmlDoc.Element ae = getAssetMetaByPath(session, assetPath);
boolean isCollection = ae.elementExists("collection");
if (isCollection) {
return ae.value("@id");
}
}
}
XmlStringWriter w = new XmlStringWriter();
String parentPath = AssetPathUtils.getParent(assetPath);
CollectionType parentType = CollectionType.collectionTypeOf(parentPath, session);
if (parentType == null) {
if (!createParents) {
// parent does not exist and not creating it
throw new FileNotFoundException("parent collection: '" + parentPath + "' does not exist.");
} else {
parentType = CollectionType.collectionTypeFor(parentPath, session);
}
}
if (parentType == CollectionType.COLLECTION_ASSET) {
w.add("pid", new String[] { "create", Boolean.toString(createParents) }, "path=" + parentPath);
} else {
w.add("namespace", new String[] { "create", Boolean.toString(createParents) }, parentPath);
}
w.add("name", AssetPathUtils.getName(assetPath));
boolean levelZeroRoot = "/".equals(parentPath);
w.add("collection",
new String[] { "unique-name-index", "true", "level-zero-root", Boolean.toString(levelZeroRoot) }, true);
XmlDoc.Element ae = session.execute("asset.create", w.document());
return ae.value("id");
}
public static long countFileAssetsInCollection(String collectionAssetPath, MFSession session) throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("collection", "path=" + collectionAssetPath);
w.add("where", "(asset has content or asset has link) and not(asset is collection)");
return session.execute("asset.count", w.document()).longValue("total");
}
public static void destroyAsset(String assetPath, MFSession session, boolean members, boolean hardDestroy)
throws Throwable {
destroyAsset(session, "path=" + assetPath, members, hardDestroy);
}
public static void destroyAsset(MFSession session, String assetId, boolean members, boolean hardDestroy)
throws Throwable {
XmlStringWriter w = new XmlStringWriter();
w.add("id", assetId);
w.add("members", members);
session.execute(hardDestroy ? "asset.hard.destroy" : "asset.destroy", w.document());
}
public static boolean isEmptyCollectionAsset(String assetPath, MFSession session) throws Throwable {
String assetId = AssetUtils.idFromPath(assetPath, session);
XmlStringWriter w = new XmlStringWriter();
w.add("where", "id=" + assetId);
w.add("where", "asset collection member count=0");
String id = session.execute("asset.query", w.document()).value("id");
return id != null && Objects.equals(assetId, id);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment