release version 1.10.0
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
<parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.base</groupId>
|
||||
<artifactId>resources</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<version>1.10.0</version>
|
||||
</parent>
|
||||
<groupId>ru.entaxy.esb.platform.runtime.base.resources</groupId>
|
||||
<artifactId>resources-service</artifactId>
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,78 +25,91 @@
|
||||
*/
|
||||
package ru.entaxy.esb.resources.impl;
|
||||
|
||||
import ru.entaxy.esb.resources.EntaxyResourceMetadata;
|
||||
import ru.entaxy.esb.resources.EntaxyResource;
|
||||
import ru.entaxy.esb.resources.EntaxyResourceMetadata;
|
||||
|
||||
public abstract class AbstractResource<T extends EntaxyResourceMetadata> implements EntaxyResource {
|
||||
|
||||
protected boolean metadataInited = false;
|
||||
|
||||
protected T metadata = null;
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata() {
|
||||
if (!metadataInited)
|
||||
initMetadata();
|
||||
return this.metadata != null;
|
||||
}
|
||||
|
||||
protected void initMetadata() {
|
||||
doInitMetadata();
|
||||
metadataInited = true;
|
||||
};
|
||||
|
||||
abstract protected void doInitMetadata();
|
||||
|
||||
abstract protected T createMetadata();
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata() {
|
||||
return getMetadata(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata(boolean create) {
|
||||
if (!metadataInited)
|
||||
initMetadata();
|
||||
if (metadata != null)
|
||||
return metadata;
|
||||
if (!create)
|
||||
return null;
|
||||
return createMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getTimestamp() {
|
||||
EntaxyResourceMetadata.MetadataSection resourceSection = getResourceSection();
|
||||
if (resourceSection == null)
|
||||
return DEFAULT_TIMESTAMP;
|
||||
try {
|
||||
return resourceSection.getContent().get(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP).getAsString();
|
||||
} catch (Exception e) {
|
||||
// NOT FOUND
|
||||
}
|
||||
return DEFAULT_TIMESTAMP;
|
||||
}
|
||||
protected boolean metadataInited = false;
|
||||
|
||||
@Override
|
||||
public final RESOURCE_SCOPE getScope() {
|
||||
EntaxyResourceMetadata.MetadataSection resourceSection = getResourceSection();
|
||||
if (resourceSection == null)
|
||||
return DEFAULT_SCOPE;
|
||||
try {
|
||||
String value = resourceSection.getContent().get(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP).getAsString();
|
||||
return RESOURCE_SCOPE.valueOf(value.toUpperCase());
|
||||
} catch (Exception e) {
|
||||
// NOT FOUND OR INCORRECT
|
||||
}
|
||||
return DEFAULT_SCOPE;
|
||||
}
|
||||
|
||||
protected EntaxyResourceMetadata.MetadataSection getResourceSection(){
|
||||
if (!hasMetadata())
|
||||
return null;
|
||||
return getMetadata().getSection(EntaxyResourceMetadata.SECTION_RESOURCE.NAME);
|
||||
}
|
||||
protected T metadata = null;
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
if (!isFolder())
|
||||
deleteMatadata();
|
||||
deleteResource();
|
||||
}
|
||||
|
||||
protected abstract void deleteMatadata();
|
||||
|
||||
protected abstract void deleteResource();
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata() {
|
||||
if (!metadataInited)
|
||||
initMetadata();
|
||||
return this.metadata != null;
|
||||
}
|
||||
|
||||
protected void initMetadata() {
|
||||
doInitMetadata();
|
||||
metadataInited = true;
|
||||
};
|
||||
|
||||
abstract protected void doInitMetadata();
|
||||
|
||||
abstract protected T createMetadata();
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata() {
|
||||
return getMetadata(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata(boolean create) {
|
||||
if (!metadataInited)
|
||||
initMetadata();
|
||||
if (metadata != null)
|
||||
return metadata;
|
||||
if (!create)
|
||||
return null;
|
||||
return createMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getTimestamp() {
|
||||
EntaxyResourceMetadata.MetadataSection resourceSection = getResourceSection();
|
||||
if (resourceSection == null)
|
||||
return DEFAULT_TIMESTAMP;
|
||||
try {
|
||||
return resourceSection.getContent().get(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP)
|
||||
.getAsString();
|
||||
} catch (Exception e) {
|
||||
// NOT FOUND
|
||||
}
|
||||
return DEFAULT_TIMESTAMP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RESOURCE_SCOPE getScope() {
|
||||
EntaxyResourceMetadata.MetadataSection resourceSection = getResourceSection();
|
||||
if (resourceSection == null)
|
||||
return DEFAULT_SCOPE;
|
||||
try {
|
||||
String value = resourceSection.getContent()
|
||||
.get(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP).getAsString();
|
||||
return RESOURCE_SCOPE.valueOf(value.toUpperCase());
|
||||
} catch (Exception e) {
|
||||
// NOT FOUND OR INCORRECT
|
||||
}
|
||||
return DEFAULT_SCOPE;
|
||||
}
|
||||
|
||||
protected EntaxyResourceMetadata.MetadataSection getResourceSection() {
|
||||
if (!hasMetadata())
|
||||
return null;
|
||||
return getMetadata().getSection(EntaxyResourceMetadata.SECTION_RESOURCE.NAME);
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -37,99 +37,102 @@ import ru.entaxy.esb.resources.EntaxyResourceProcessor;
|
||||
|
||||
public class ResourceWrapper implements EntaxyResource {
|
||||
|
||||
protected EntaxyResource origin;
|
||||
protected List<EntaxyResourceProcessor> processors;
|
||||
protected String originProtocol;
|
||||
protected String originLocation;
|
||||
|
||||
public ResourceWrapper(EntaxyResource originResource
|
||||
, String originProtocol
|
||||
, String originLocation
|
||||
, List<EntaxyResourceProcessor> resourceProcessors) {
|
||||
this.origin = originResource;
|
||||
this.originProtocol = originProtocol;
|
||||
this.originLocation = originLocation;
|
||||
this.processors = resourceProcessors==null
|
||||
?Collections.emptyList()
|
||||
:new ArrayList<>(resourceProcessors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return origin.getInputStream();
|
||||
}
|
||||
protected EntaxyResource origin;
|
||||
protected List<EntaxyResourceProcessor> processors;
|
||||
protected String originProtocol;
|
||||
protected String originLocation;
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
return origin.getAsString();
|
||||
}
|
||||
public ResourceWrapper(EntaxyResource originResource, String originProtocol, String originLocation,
|
||||
List<EntaxyResourceProcessor> resourceProcessors) {
|
||||
this.origin = originResource;
|
||||
this.originProtocol = originProtocol;
|
||||
this.originLocation = originLocation;
|
||||
this.processors = resourceProcessors == null
|
||||
? Collections.emptyList()
|
||||
: new ArrayList<>(resourceProcessors);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(InputStream inputStream) {
|
||||
InputStream current = inputStream;
|
||||
for (EntaxyResourceProcessor processor: processors) {
|
||||
InputStream prev = current;
|
||||
current = processor.preProcess(current, this);
|
||||
if (current == null)
|
||||
current = prev;
|
||||
}
|
||||
origin.save(current);
|
||||
for (EntaxyResourceProcessor processor: processors)
|
||||
processor.postProcess(this);
|
||||
}
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
return origin.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return origin.exists();
|
||||
}
|
||||
@Override
|
||||
public String getAsString() {
|
||||
return origin.getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFolder() {
|
||||
return origin.isFolder();
|
||||
}
|
||||
@Override
|
||||
public void delete() {
|
||||
origin.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return origin.getName();
|
||||
}
|
||||
@Override
|
||||
public void save(InputStream inputStream) {
|
||||
InputStream current = inputStream;
|
||||
for (EntaxyResourceProcessor processor : processors) {
|
||||
InputStream prev = current;
|
||||
current = processor.preProcess(current, this);
|
||||
if (current == null)
|
||||
current = prev;
|
||||
}
|
||||
origin.save(current);
|
||||
for (EntaxyResourceProcessor processor : processors)
|
||||
processor.postProcess(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return origin.getSize();
|
||||
}
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return origin.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getLocation() {
|
||||
return origin.getLocation();
|
||||
}
|
||||
@Override
|
||||
public boolean isFolder() {
|
||||
return origin.isFolder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata() {
|
||||
return origin.hasMetadata();
|
||||
}
|
||||
@Override
|
||||
public String getName() {
|
||||
return origin.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata() {
|
||||
return origin.getMetadata();
|
||||
}
|
||||
@Override
|
||||
public long getSize() {
|
||||
return origin.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata(boolean create) {
|
||||
return origin.getMetadata(create);
|
||||
}
|
||||
@Override
|
||||
public URL getLocation() {
|
||||
return origin.getLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURL() {
|
||||
return this.originProtocol + ":" + originLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTimestamp() {
|
||||
return origin.getTimestamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RESOURCE_SCOPE getScope() {
|
||||
return origin.getScope();
|
||||
}
|
||||
@Override
|
||||
public boolean hasMetadata() {
|
||||
return origin.hasMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata() {
|
||||
return origin.getMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyResourceMetadata getMetadata(boolean create) {
|
||||
return origin.getMetadata(create);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURL() {
|
||||
return this.originProtocol + ":" + originLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTimestamp() {
|
||||
return origin.getTimestamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RESOURCE_SCOPE getScope() {
|
||||
return origin.getScope();
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,7 +25,10 @@
|
||||
*/
|
||||
package ru.entaxy.esb.resources.impl.service;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
@ -43,165 +46,343 @@ import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import ru.entaxy.esb.resources.EntaxyResource;
|
||||
import ru.entaxy.esb.resources.EntaxyResourceMetadata;
|
||||
import ru.entaxy.esb.resources.EntaxyResourceProcessor;
|
||||
import ru.entaxy.esb.resources.EntaxyResourceProvider;
|
||||
import ru.entaxy.esb.resources.EntaxyResourceProviderProxy;
|
||||
import ru.entaxy.esb.resources.EntaxyResourceService;
|
||||
import ru.entaxy.esb.resources.EntaxyResourceURLFactory;
|
||||
import ru.entaxy.esb.resources.impl.ResourceWrapper;
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
|
||||
@Component (service = EntaxyResourceService.class, immediate = true)
|
||||
@Component(service = EntaxyResourceService.class, immediate = true)
|
||||
public class EntaxyResourceServiceImpl implements EntaxyResourceService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(EntaxyResourceServiceImpl.class);
|
||||
|
||||
protected BundleContext bundleContext;
|
||||
private static final Logger log = LoggerFactory.getLogger(EntaxyResourceServiceImpl.class);
|
||||
|
||||
protected ProvidersController controller;
|
||||
|
||||
@Activate
|
||||
public EntaxyResourceServiceImpl(BundleContext bundleContext) {
|
||||
super();
|
||||
this.bundleContext = bundleContext;
|
||||
this.controller = new ProvidersController(bundleContext, this);
|
||||
}
|
||||
|
||||
@Reference (cardinality = ReferenceCardinality.MULTIPLE, collectionType = CollectionType.SERVICE
|
||||
, policyOption = ReferencePolicyOption.GREEDY
|
||||
, unbind = "removeProvider"
|
||||
, policy = ReferencePolicy.DYNAMIC)
|
||||
public void addProvider(EntaxyResourceProvider provider) {
|
||||
controller.addProvider(provider);
|
||||
}
|
||||
|
||||
public void removeProvider(EntaxyResourceProvider provider) {
|
||||
controller.removeProvider(provider);
|
||||
}
|
||||
|
||||
@Reference (cardinality = ReferenceCardinality.MULTIPLE, collectionType = CollectionType.SERVICE
|
||||
, policyOption = ReferencePolicyOption.GREEDY
|
||||
, unbind = "removeProxy"
|
||||
, policy = ReferencePolicy.DYNAMIC)
|
||||
public void addProxy(EntaxyResourceProviderProxy proxy) {
|
||||
controller.addProxy(proxy);
|
||||
}
|
||||
protected BundleContext bundleContext;
|
||||
|
||||
public void removeProxy(EntaxyResourceProviderProxy proxy) {
|
||||
controller.removeProxy(proxy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtocolAvailable(String protocol) {
|
||||
return controller.hasProvider(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerProtocolCallback(String protocol, EntaxyResourceProtocolAvailableCallback callback) {
|
||||
controller.registerProtocolCallback(protocol, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyResource getResource(String location) {
|
||||
if (!CommonUtils.isValid(location))
|
||||
return null;
|
||||
int index = location.indexOf(":");
|
||||
if (index>0) {
|
||||
String protocol = location.substring(0, index);
|
||||
String path = location.substring(index+1);
|
||||
if (controller.hasProvider(protocol)) {
|
||||
return wrapResource(controller.getProvider(protocol).getResource(path)
|
||||
, protocol
|
||||
, path);
|
||||
} else {
|
||||
log.warn("Provider not found for: [{}]", location);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
protected ProvidersController controller;
|
||||
|
||||
@Override
|
||||
public List<EntaxyResource> getResources(String location) {
|
||||
if (!CommonUtils.isValid(location))
|
||||
return Collections.emptyList();
|
||||
int index = location.indexOf(":");
|
||||
String protocol, path = "";
|
||||
if (index>0) {
|
||||
protocol = location.substring(0, index);
|
||||
path = location.substring(index+1);
|
||||
} else {
|
||||
protocol = location;
|
||||
}
|
||||
if (controller.hasProvider(protocol)) {
|
||||
List<EntaxyResource> resources = controller.getProvider(protocol).getResources(path);
|
||||
if (resources==null)
|
||||
return Collections.emptyList();
|
||||
|
||||
final String rootPath = path;
|
||||
|
||||
return resources.stream()
|
||||
.map(r -> wrapResource(r, protocol, rootPath + "/" + r.getName()))
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
log.warn("Provider not found for: [{}]", location);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@Activate
|
||||
public EntaxyResourceServiceImpl(BundleContext bundleContext) {
|
||||
super();
|
||||
this.bundleContext = bundleContext;
|
||||
this.controller = new ProvidersController(bundleContext, this);
|
||||
}
|
||||
|
||||
protected void updateResourceTimestamp(EntaxyResource resource, String timestamp) {
|
||||
if (resource == null)
|
||||
return;
|
||||
if (!resource.isFolder() && !resource.exists())
|
||||
return;
|
||||
EntaxyResourceMetadata metadata = resource.getMetadata(true);
|
||||
EntaxyResourceMetadata.MetadataSection section = metadata.getSection(EntaxyResourceMetadata.SECTION_RESOURCE.NAME);
|
||||
section.getContent().remove(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP);
|
||||
section.getContent().addProperty(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP
|
||||
, timestamp);
|
||||
metadata.update();
|
||||
}
|
||||
|
||||
protected void updateParentTimestamps(EntaxyResource resource, String timestamp) {
|
||||
String url = resource.getURL();
|
||||
while (url.lastIndexOf('/') > 0) {
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
updateResourceTimestamp(getResource(url), timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
protected EntaxyResource wrapResource(EntaxyResource origin, String originProtocol, String originLocation) {
|
||||
return new StandardResourceWrapper(origin, originProtocol, originLocation, this);
|
||||
}
|
||||
|
||||
protected static class StandardResourceWrapper extends ResourceWrapper implements EntaxyResourceProcessor {
|
||||
|
||||
EntaxyResourceServiceImpl service;
|
||||
|
||||
public StandardResourceWrapper(EntaxyResource origin, String originProtocol, String originLocation, EntaxyResourceServiceImpl serviceImpl) {
|
||||
super(origin, originProtocol, originLocation, new ArrayList<>());
|
||||
this.processors.add(this);
|
||||
this.service = serviceImpl;
|
||||
}
|
||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, collectionType = CollectionType.SERVICE,
|
||||
policyOption = ReferencePolicyOption.GREEDY, unbind = "removeProvider", policy = ReferencePolicy.DYNAMIC)
|
||||
public void addProvider(EntaxyResourceProvider provider) {
|
||||
controller.addProvider(provider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream preProcess(InputStream origin, EntaxyResource resource) {
|
||||
return null;
|
||||
}
|
||||
public void removeProvider(EntaxyResourceProvider provider) {
|
||||
controller.removeProvider(provider);
|
||||
}
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MULTIPLE, collectionType = CollectionType.SERVICE,
|
||||
policyOption = ReferencePolicyOption.GREEDY, unbind = "removeProxy", policy = ReferencePolicy.DYNAMIC)
|
||||
public void addProxy(EntaxyResourceProviderProxy proxy) {
|
||||
controller.addProxy(proxy);
|
||||
}
|
||||
|
||||
public void removeProxy(EntaxyResourceProviderProxy proxy) {
|
||||
controller.removeProxy(proxy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtocolAvailable(String protocol) {
|
||||
return controller.hasProvider(protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerProtocolCallback(String protocol, EntaxyResourceProtocolAvailableCallback callback) {
|
||||
controller.registerProtocolCallback(protocol, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntaxyResource getResource(String resourceLocation) {
|
||||
if (!CommonUtils.isValid(resourceLocation))
|
||||
return null;
|
||||
String location = resourceLocation;
|
||||
try {
|
||||
location = EntaxyResourceURLFactory.getLocalUri(resourceLocation).toString();
|
||||
} catch (URISyntaxException e) {
|
||||
log.warn(String.format("Failed getting local URI for [%s]", resourceLocation), e);
|
||||
}
|
||||
int index = location.indexOf(":");
|
||||
if (index > 0) {
|
||||
String protocol = location.substring(0, index);
|
||||
String path = location.substring(index + 1);
|
||||
if (controller.hasProvider(protocol)) {
|
||||
return wrapResource(controller.getProvider(protocol).getResource(path), protocol, path);
|
||||
} else {
|
||||
log.warn("Provider not found for: [{}]", location);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EntaxyResource> getResources(String resourceLocation) {
|
||||
if (!CommonUtils.isValid(resourceLocation))
|
||||
return Collections.emptyList();
|
||||
|
||||
String location = resourceLocation;
|
||||
try {
|
||||
location = EntaxyResourceURLFactory.getLocalUri(resourceLocation).toString();
|
||||
} catch (URISyntaxException e) {
|
||||
log.warn(String.format("Failed getting local URI for [%s]", resourceLocation), e);
|
||||
}
|
||||
|
||||
int index = location.indexOf(":");
|
||||
String protocol, path = "";
|
||||
if (index > 0) {
|
||||
protocol = location.substring(0, index);
|
||||
path = location.substring(index + 1);
|
||||
} else {
|
||||
protocol = location;
|
||||
}
|
||||
if (controller.hasProvider(protocol)) {
|
||||
List<EntaxyResource> resources = controller.getProvider(protocol).getResources(path);
|
||||
if (resources == null)
|
||||
return Collections.emptyList();
|
||||
|
||||
final String rootPath = path;
|
||||
|
||||
return resources.stream()
|
||||
.map(r -> wrapResource(r, protocol, rootPath + "/" + r.getName()))
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
log.warn("Provider not found for: [{}]", location);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateResourceTimestamp(EntaxyResource resource, String timestamp) {
|
||||
if (resource == null)
|
||||
return;
|
||||
if (!resource.isFolder() && !resource.exists())
|
||||
return;
|
||||
EntaxyResourceMetadata metadata = resource.getMetadata(true);
|
||||
EntaxyResourceMetadata.MetadataSection section =
|
||||
metadata.getSection(EntaxyResourceMetadata.SECTION_RESOURCE.NAME);
|
||||
section.getContent().remove(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP);
|
||||
section.getContent().addProperty(EntaxyResourceMetadata.SECTION_RESOURCE.ATTRIBUTES.TIMESTAMP, timestamp);
|
||||
metadata.update();
|
||||
}
|
||||
|
||||
protected void updateParentTimestamps(EntaxyResource resource, String timestamp) {
|
||||
String url = resource.getURL();
|
||||
while (url.lastIndexOf('/') > 0) {
|
||||
url = url.substring(0, url.lastIndexOf('/'));
|
||||
updateResourceTimestamp(getResource(url), timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
protected EntaxyResource wrapResource(EntaxyResource origin, String originProtocol, String originLocation) {
|
||||
// check if it's sequence resource
|
||||
if (origin.getName().startsWith("$")) {
|
||||
EntaxyResourceMetadata.MetadataSection section =
|
||||
origin.getMetadata(true).getSection(EntaxyResourceMetadata.SECTION_RESOURCE.NAME);
|
||||
if (section.getContent().has("@SEQUENCE")) {
|
||||
JsonElement je = section.getContent().get("@SEQUENCE");
|
||||
if (je.isJsonObject()) {
|
||||
return new SequenceResourceWrapper(origin, originProtocol, originLocation, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new StandardResourceWrapper(origin, originProtocol, originLocation, this);
|
||||
}
|
||||
|
||||
protected static class SequenceResourceWrapper extends ResourceWrapper implements EntaxyResourceProcessor {
|
||||
|
||||
EntaxyResourceServiceImpl service;
|
||||
|
||||
String delimiter = null;
|
||||
|
||||
List<SequenceItem> sequence;
|
||||
|
||||
protected abstract class SequenceItem {
|
||||
abstract boolean isRequired();
|
||||
|
||||
abstract InputStream getInputStream();
|
||||
|
||||
abstract long getSize();
|
||||
}
|
||||
|
||||
protected class ResourceSequenceItem extends SequenceItem {
|
||||
|
||||
EntaxyResource entaxyResource;
|
||||
|
||||
boolean required = false;
|
||||
|
||||
public ResourceSequenceItem(EntaxyResource entaxyResource, boolean required) {
|
||||
this.entaxyResource = entaxyResource;
|
||||
this.required = required;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isRequired() {
|
||||
return required;
|
||||
}
|
||||
|
||||
@Override
|
||||
InputStream getInputStream() {
|
||||
return entaxyResource.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
long getSize() {
|
||||
return entaxyResource.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
protected class StringSequenceItem extends SequenceItem {
|
||||
|
||||
String value;
|
||||
|
||||
public StringSequenceItem(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isRequired() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
InputStream getInputStream() {
|
||||
return new ByteArrayInputStream(value.getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
long getSize() {
|
||||
return value.length();
|
||||
}
|
||||
}
|
||||
|
||||
public SequenceResourceWrapper(EntaxyResource origin, String originProtocol, String originLocation,
|
||||
EntaxyResourceServiceImpl serviceImpl) {
|
||||
super(origin, originProtocol, originLocation, new ArrayList<>());
|
||||
this.processors.add(this);
|
||||
this.service = serviceImpl;
|
||||
|
||||
buildSequence();
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected void buildSequence() {
|
||||
|
||||
sequence = new ArrayList<>();
|
||||
|
||||
JsonObject sequenceContent =
|
||||
origin.getMetadata(true).getSection(EntaxyResourceMetadata.SECTION_RESOURCE.NAME).getContent()
|
||||
.get("@SEQUENCE").getAsJsonObject();
|
||||
try {
|
||||
delimiter = sequenceContent.get("delimiter").getAsString().replace("__LF__", "\n");
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
try {
|
||||
JsonArray arr = sequenceContent.get("items").getAsJsonArray();
|
||||
for (int i = 0; i < arr.size() - 1; i++) {
|
||||
String url = arr.get(i).getAsJsonObject().get("url").getAsString();
|
||||
boolean required = false;
|
||||
try {
|
||||
required = arr.get(i).getAsJsonObject().get("required").getAsBoolean();
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
EntaxyResource resource = service.getResource(url);
|
||||
ResourceSequenceItem si = new ResourceSequenceItem(resource, required);
|
||||
sequence.add(si);
|
||||
if (delimiter != null)
|
||||
sequence.add(new StringSequenceItem(delimiter));
|
||||
}
|
||||
|
||||
String url = arr.get(arr.size() - 1).getAsJsonObject().get("url").getAsString();
|
||||
boolean required = false;
|
||||
try {
|
||||
required = arr.get(arr.size() - 1).getAsJsonObject().get("required").getAsBoolean();
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
EntaxyResource resource = service.getResource(url);
|
||||
ResourceSequenceItem si = new ResourceSequenceItem(resource, required);
|
||||
sequence.add(si);
|
||||
|
||||
} catch (Exception ignore) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
long size = 0;
|
||||
for (SequenceItem si : sequence)
|
||||
size += si.getSize();
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
SequenceInputStream sequenceInputStream = new SequenceInputStream(Collections
|
||||
.enumeration(sequence.stream().map(item -> item.getInputStream()).collect(Collectors.toList())));
|
||||
return sequenceInputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream preProcess(InputStream origin, EntaxyResource resource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(EntaxyResource resource) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class StandardResourceWrapper extends ResourceWrapper implements EntaxyResourceProcessor {
|
||||
|
||||
EntaxyResourceServiceImpl service;
|
||||
|
||||
public StandardResourceWrapper(EntaxyResource origin, String originProtocol, String originLocation,
|
||||
EntaxyResourceServiceImpl serviceImpl) {
|
||||
super(origin, originProtocol, originLocation, new ArrayList<>());
|
||||
this.processors.add(this);
|
||||
this.service = serviceImpl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream preProcess(InputStream origin, EntaxyResource resource) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(EntaxyResource resource) {
|
||||
String timestamp = "" + Calendar.getInstance().getTimeInMillis();
|
||||
service.updateResourceTimestamp(resource, timestamp);
|
||||
service.updateParentTimestamps(resource, timestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(InputStream inputStream) {
|
||||
// origin.save(inputStream);
|
||||
super.save(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(EntaxyResource resource) {
|
||||
String timestamp = "" + Calendar.getInstance().getTimeInMillis();
|
||||
service.updateResourceTimestamp(resource, timestamp);
|
||||
service.updateParentTimestamps(resource, timestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(InputStream inputStream) {
|
||||
// origin.save(inputStream);
|
||||
super.save(inputStream);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -43,107 +43,117 @@ import ru.entaxy.esb.resources.EntaxyResourceService.EntaxyResourceProtocolAvail
|
||||
|
||||
public class ProvidersController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ProvidersController.class);
|
||||
|
||||
protected BundleContext bundleContext;
|
||||
private static final Logger log = LoggerFactory.getLogger(ProvidersController.class);
|
||||
|
||||
protected EntaxyResourceService resourceService;
|
||||
|
||||
protected Map<String, EntaxyResourceProvider> providers = new ConcurrentHashMap<>();
|
||||
protected BundleContext bundleContext;
|
||||
|
||||
protected Map<String, ProxyController> proxies = new ConcurrentHashMap<>();
|
||||
|
||||
protected Map<String, String> dependencies = new HashMap<>();
|
||||
|
||||
protected Map<String, List<EntaxyResourceProtocolAvailableCallback>> callbacks = new ConcurrentHashMap<String, List<EntaxyResourceProtocolAvailableCallback>>();
|
||||
|
||||
public ProvidersController(BundleContext bundleContext, EntaxyResourceService resourceService) {
|
||||
super();
|
||||
this.bundleContext = bundleContext;
|
||||
this.resourceService = resourceService;
|
||||
}
|
||||
|
||||
public boolean hasProvider(String protocol) {
|
||||
return this.providers.containsKey(protocol);
|
||||
}
|
||||
|
||||
public EntaxyResourceProvider getProvider(String protocol) {
|
||||
return this.providers.getOrDefault(protocol, null);
|
||||
}
|
||||
|
||||
public void registerProtocolCallback(String protocol, EntaxyResourceProtocolAvailableCallback callback) {
|
||||
if (!callbacks.containsKey(protocol))
|
||||
callbacks.put(protocol, new ArrayList<>());
|
||||
callbacks.get(protocol).add(callback);
|
||||
}
|
||||
|
||||
public void addProvider(EntaxyResourceProvider provider) {
|
||||
this.providers.put(provider.getProtocol(), provider);
|
||||
if (callbacks.containsKey(provider.getProtocol())) {
|
||||
for (EntaxyResourceProtocolAvailableCallback callback: callbacks.get(provider.getProtocol()))
|
||||
callback.protocolAvailable();
|
||||
callbacks.remove(provider.getProtocol());
|
||||
}
|
||||
log.info("RESOURCE PROVIDER ADDED: " + provider.getProtocol());
|
||||
activateCascadeFrom(provider.getProtocol());
|
||||
}
|
||||
protected EntaxyResourceService resourceService;
|
||||
|
||||
public void removeProvider(EntaxyResourceProvider provider) {
|
||||
deactivateCascadeFrom(provider.getProtocol());
|
||||
this.providers.remove(provider.getProtocol());
|
||||
}
|
||||
|
||||
public void addProxy(EntaxyResourceProviderProxy proxy) {
|
||||
this.proxies.put(proxy.getProtocol()
|
||||
, new ProxyController(bundleContext, proxy, resourceService));
|
||||
addDependency(proxy.getTargetProtocol(), proxy.getProtocol());
|
||||
if (isDependenciesSatisfied(proxy.getProtocol()))
|
||||
activateProxy(proxy.getProtocol());
|
||||
}
|
||||
protected Map<String, EntaxyResourceProvider> providers = new ConcurrentHashMap<>();
|
||||
|
||||
public void removeProxy(EntaxyResourceProviderProxy proxy) {
|
||||
this.proxies.remove(proxy.getProtocol());
|
||||
}
|
||||
|
||||
protected void addDependency(String target, String proxy) {
|
||||
this.dependencies.put(proxy, target);
|
||||
}
|
||||
|
||||
protected boolean isDependenciesSatisfied(String proxy) {
|
||||
if (!this.dependencies.containsKey(proxy))
|
||||
return true;
|
||||
return this.hasProvider(this.dependencies.get(proxy));
|
||||
}
|
||||
|
||||
protected void activateCascadeFrom(String protocol) {
|
||||
for (String proxy: getDependentsFor(protocol)) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).activate();
|
||||
}
|
||||
}
|
||||
protected Object providersLock = new Object();
|
||||
|
||||
protected void deactivateCascadeFrom(String protocol) {
|
||||
for (String proxy: getDependentsFor(protocol)) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
protected List<String> getDependentsFor(String target){
|
||||
return this.dependencies.entrySet().stream()
|
||||
.filter(e -> e.getValue().equals(target))
|
||||
.map(e -> e.getKey())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected void activateProxy(String proxy) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).activate();
|
||||
}
|
||||
protected Map<String, ProxyController> proxies = new ConcurrentHashMap<>();
|
||||
|
||||
protected Map<String, String> dependencies = new HashMap<>();
|
||||
|
||||
protected Map<String, List<EntaxyResourceProtocolAvailableCallback>> callbacks =
|
||||
new ConcurrentHashMap<String, List<EntaxyResourceProtocolAvailableCallback>>();
|
||||
|
||||
public ProvidersController(BundleContext bundleContext, EntaxyResourceService resourceService) {
|
||||
super();
|
||||
this.bundleContext = bundleContext;
|
||||
this.resourceService = resourceService;
|
||||
}
|
||||
|
||||
public boolean hasProvider(String protocol) {
|
||||
return this.providers.containsKey(protocol);
|
||||
}
|
||||
|
||||
public EntaxyResourceProvider getProvider(String protocol) {
|
||||
return this.providers.getOrDefault(protocol, null);
|
||||
}
|
||||
|
||||
public void registerProtocolCallback(String protocol, EntaxyResourceProtocolAvailableCallback callback) {
|
||||
if (!callbacks.containsKey(protocol))
|
||||
callbacks.put(protocol, new ArrayList<>());
|
||||
|
||||
synchronized (providersLock) {
|
||||
if (hasProvider(protocol))
|
||||
callback.protocolAvailable();
|
||||
else
|
||||
callbacks.get(protocol).add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public void addProvider(EntaxyResourceProvider provider) {
|
||||
synchronized (providersLock) {
|
||||
this.providers.put(provider.getProtocol(), provider);
|
||||
}
|
||||
if (callbacks.containsKey(provider.getProtocol())) {
|
||||
for (EntaxyResourceProtocolAvailableCallback callback : callbacks.get(provider.getProtocol()))
|
||||
callback.protocolAvailable();
|
||||
callbacks.remove(provider.getProtocol());
|
||||
}
|
||||
log.info("RESOURCE PROVIDER ADDED: " + provider.getProtocol());
|
||||
activateCascadeFrom(provider.getProtocol());
|
||||
}
|
||||
|
||||
public void removeProvider(EntaxyResourceProvider provider) {
|
||||
deactivateCascadeFrom(provider.getProtocol());
|
||||
this.providers.remove(provider.getProtocol());
|
||||
}
|
||||
|
||||
public void addProxy(EntaxyResourceProviderProxy proxy) {
|
||||
this.proxies.put(proxy.getProtocol(), new ProxyController(bundleContext, proxy, resourceService));
|
||||
addDependency(proxy.getTargetProtocol(), proxy.getProtocol());
|
||||
if (isDependenciesSatisfied(proxy.getProtocol()))
|
||||
activateProxy(proxy.getProtocol());
|
||||
}
|
||||
|
||||
public void removeProxy(EntaxyResourceProviderProxy proxy) {
|
||||
this.proxies.remove(proxy.getProtocol());
|
||||
}
|
||||
|
||||
protected void addDependency(String target, String proxy) {
|
||||
this.dependencies.put(proxy, target);
|
||||
}
|
||||
|
||||
protected boolean isDependenciesSatisfied(String proxy) {
|
||||
if (!this.dependencies.containsKey(proxy))
|
||||
return true;
|
||||
return this.hasProvider(this.dependencies.get(proxy));
|
||||
}
|
||||
|
||||
protected void activateCascadeFrom(String protocol) {
|
||||
for (String proxy : getDependentsFor(protocol)) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).activate();
|
||||
}
|
||||
}
|
||||
|
||||
protected void deactivateCascadeFrom(String protocol) {
|
||||
for (String proxy : getDependentsFor(protocol)) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
protected List<String> getDependentsFor(String target) {
|
||||
return this.dependencies.entrySet().stream()
|
||||
.filter(e -> e.getValue().equals(target))
|
||||
.map(e -> e.getKey())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected void activateProxy(String proxy) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).activate();
|
||||
}
|
||||
|
||||
protected void deactivateProxy(String proxy) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).deactivate();
|
||||
}
|
||||
|
||||
protected void deactivateProxy(String proxy) {
|
||||
if (this.proxies.containsKey(proxy))
|
||||
this.proxies.get(proxy).deactivate();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -62,298 +62,324 @@ import ru.entaxy.platform.base.support.JSONUtils;
|
||||
|
||||
public class FileResourceProvider extends AbstractResourceProvider {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FileResourceProvider.class);
|
||||
|
||||
public static final String METADATA_FILE_EXTENSION = "e_r_meta";
|
||||
|
||||
private String rootDirectory;
|
||||
private File root;
|
||||
|
||||
public String getRootDirectory() {
|
||||
return rootDirectory;
|
||||
}
|
||||
private static final Logger log = LoggerFactory.getLogger(FileResourceProvider.class);
|
||||
|
||||
public void setRootDirectory(String rootDirectory) {
|
||||
this.rootDirectory = rootDirectory;
|
||||
root = new File(this.rootDirectory);
|
||||
if (!root.exists())
|
||||
root.mkdirs();
|
||||
}
|
||||
public static final String METADATA_FILE_EXTENSION = "e_r_meta";
|
||||
|
||||
@Override
|
||||
protected EntaxyResource doGetResource(String location) {
|
||||
Path rootPath = root.toPath();
|
||||
Path targetPath = Paths.get(rootPath.toString(), location);
|
||||
log.debug("TARGET PATH :: " + targetPath.toAbsolutePath().toString());
|
||||
File targetFile = new File(targetPath.toAbsolutePath().toString());
|
||||
log.debug("TARGET FILE :: " + targetFile.getAbsolutePath());
|
||||
return new FileResource(targetFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<EntaxyResource> doGetResources(String location) {
|
||||
Path rootPath = root.toPath();
|
||||
Path targetPath = Paths.get(rootPath.toString(), location);
|
||||
log.debug("TARGET PATH :: " + targetPath.toAbsolutePath().toString());
|
||||
File targetFile = new File(targetPath.toAbsolutePath().toString());
|
||||
if (!targetFile.exists())
|
||||
return null;
|
||||
if (!targetFile.isDirectory())
|
||||
return null;
|
||||
return Stream.of(targetFile.listFiles())
|
||||
.filter(f -> isFileterd(f))
|
||||
.map(f -> new FileResource(f))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
}
|
||||
private String rootDirectory;
|
||||
private File root;
|
||||
|
||||
protected boolean isFileterd(File f) {
|
||||
return f.isDirectory() || !f.getName().endsWith(METADATA_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
public static class FileResourceMetadata implements EntaxyResourceMetadata {
|
||||
public String getRootDirectory() {
|
||||
return rootDirectory;
|
||||
}
|
||||
|
||||
public static class JsonMetadataSection implements EntaxyResourceMetadata.MetadataSection {
|
||||
public void setRootDirectory(String rootDirectory) {
|
||||
this.rootDirectory = rootDirectory;
|
||||
root = new File(this.rootDirectory);
|
||||
if (!root.exists())
|
||||
root.mkdirs();
|
||||
}
|
||||
|
||||
String name;
|
||||
JsonObject content;
|
||||
|
||||
public JsonMetadataSection(String name, JsonObject content) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
@Override
|
||||
protected EntaxyResource doGetResource(String location) {
|
||||
Path rootPath = root.toPath();
|
||||
Path targetPath = Paths.get(rootPath.toString(), location);
|
||||
log.debug("TARGET PATH :: " + targetPath.toAbsolutePath().toString());
|
||||
File targetFile = new File(targetPath.toAbsolutePath().toString());
|
||||
log.debug("TARGET FILE :: " + targetFile.getAbsolutePath());
|
||||
return new FileResource(targetFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(FileResourceProvider.FileResourceMetadata.class);
|
||||
|
||||
protected static Gson GSON = (new GsonBuilder())
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
|
||||
protected File metadataFile;
|
||||
|
||||
protected JsonObject root;
|
||||
|
||||
protected Map<String, JsonMetadataSection> sections = null;
|
||||
|
||||
public FileResourceMetadata(File metadataFile) {
|
||||
super();
|
||||
this.metadataFile = metadataFile;
|
||||
if (this.metadataFile.exists()) {
|
||||
try {
|
||||
this.root = JSONUtils.getJsonRootObject(metadataFile.toURI().toURL());
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading metadata from [" + this.metadataFile.getAbsolutePath() + "]", e);
|
||||
this.root = new JsonObject();
|
||||
}
|
||||
} else {
|
||||
this.root = new JsonObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
return metadataFile.exists();
|
||||
}
|
||||
|
||||
protected void initSections() {
|
||||
if (this.sections == null) {
|
||||
this.sections = new HashMap<>();
|
||||
for (Entry<String, JsonElement> entry: root.entrySet()) {
|
||||
if (entry.getValue().isJsonObject()) {
|
||||
sections.put(entry.getKey()
|
||||
, new JsonMetadataSection(entry.getKey()
|
||||
, entry.getValue().getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetadataSection> getSections() {
|
||||
initSections();
|
||||
return this.sections.values().stream()
|
||||
.map(m -> (MetadataSection)m)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@Override
|
||||
protected List<EntaxyResource> doGetResources(String location) {
|
||||
Path rootPath = root.toPath();
|
||||
Path targetPath = Paths.get(rootPath.toString(), location);
|
||||
log.debug("TARGET PATH :: " + targetPath.toAbsolutePath().toString());
|
||||
File targetFile = new File(targetPath.toAbsolutePath().toString());
|
||||
if (!targetFile.exists())
|
||||
return null;
|
||||
if (!targetFile.isDirectory())
|
||||
return null;
|
||||
return Stream.of(targetFile.listFiles())
|
||||
.filter(f -> isFiltered(f))
|
||||
.map(f -> new FileResource(f))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
@Override
|
||||
public boolean hasSection(String sectionName) {
|
||||
initSections();
|
||||
return this.sections.containsKey(sectionName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataSection getSection(String sectionName) {
|
||||
if (!hasSection(sectionName)) {
|
||||
this.sections.put(sectionName, new JsonMetadataSection(sectionName, new JsonObject()));
|
||||
}
|
||||
return this.sections.get(sectionName);
|
||||
}
|
||||
protected boolean isFiltered(File f) {
|
||||
return f.isDirectory() || !f.getName().endsWith(METADATA_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
for (JsonMetadataSection section: sections.values()) {
|
||||
JSONUtils.replaceValue(root, section.getName(), section.content);
|
||||
}
|
||||
try {
|
||||
FileUtils.string2file(root.toString(), metadataFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Error saving file [" + metadataFile.getAbsolutePath() + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getAsJson() {
|
||||
JsonObject result = root.deepCopy();
|
||||
if (sections == null)
|
||||
initSections();
|
||||
for (JsonMetadataSection section: sections.values()) {
|
||||
JSONUtils.replaceValue(result, section.getName(), section.content);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FileResource extends AbstractResource<FileResourceMetadata> {
|
||||
|
||||
private File file;
|
||||
|
||||
private File metadataFile;
|
||||
|
||||
public FileResource(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
public static class FileResourceMetadata implements EntaxyResourceMetadata {
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
if (!exists())
|
||||
return null;
|
||||
if (file.isDirectory())
|
||||
return null;
|
||||
try {
|
||||
return file.toURI().toURL().openStream();
|
||||
} catch (IOException e) {
|
||||
FileResourceProvider.log.error("Error getting resource", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static class JsonMetadataSection implements EntaxyResourceMetadata.MetadataSection {
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
if (!exists())
|
||||
return null;
|
||||
if (file.isDirectory())
|
||||
return "";
|
||||
try {
|
||||
return IOUtils.toString(getInputStream());
|
||||
} catch (IOException e) {
|
||||
FileResourceProvider.log.error("Error getting resource as string", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
String name;
|
||||
JsonObject content;
|
||||
|
||||
@Override
|
||||
public void save(InputStream inputStream) {
|
||||
if (!file.exists())
|
||||
try {
|
||||
log.debug("\nMAKE DIRS", file.getParentFile().getAbsolutePath());
|
||||
file.getParentFile().mkdirs();
|
||||
// file.createNewFile();
|
||||
} catch (Exception e1) {
|
||||
log.error("Error creating resource", e1);
|
||||
}
|
||||
if (file.isDirectory())
|
||||
return;
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)){
|
||||
FileChannel channel = fileOutputStream.getChannel();
|
||||
FileLock lock = channel.lock();
|
||||
byte[] bytes = IOUtils.toByteArray(inputStream);
|
||||
channel.write(ByteBuffer.wrap(bytes));
|
||||
|
||||
lock.release();
|
||||
channel.close();
|
||||
IOUtils.closeQuietly(fileOutputStream);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error saving resource", e);
|
||||
}
|
||||
}
|
||||
public JsonMetadataSection(String name, JsonObject content) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return file.exists();
|
||||
}
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getLocation() {
|
||||
try {
|
||||
return this.file.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public JsonObject getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFolder() {
|
||||
return file.isDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return file.getName();
|
||||
}
|
||||
private static final Logger log = LoggerFactory.getLogger(FileResourceProvider.FileResourceMetadata.class);
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
try {
|
||||
if (file.isFile())
|
||||
return Files.size(file.toPath());
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
log.warn("Error getting file size for [" + file.getAbsolutePath() + "]", e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
protected static Gson GSON = (new GsonBuilder())
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
|
||||
@Override
|
||||
protected void doInitMetadata() {
|
||||
String metadataFileName = (file.isDirectory()?"":file.getName())
|
||||
+ "." + FileResourceProvider.METADATA_FILE_EXTENSION;
|
||||
Path metadataFilePath = Path.of(
|
||||
(file.isDirectory()
|
||||
?file
|
||||
:file.getParentFile()).toPath().toString(), metadataFileName);
|
||||
metadataFile = metadataFilePath.toFile();
|
||||
if (metadataFile.exists())
|
||||
this.metadata = new FileResourceMetadata(metadataFile);
|
||||
}
|
||||
protected File metadataFile;
|
||||
|
||||
@Override
|
||||
protected FileResourceMetadata createMetadata() {
|
||||
if (!metadataFile.exists())
|
||||
this.metadata = new FileResourceMetadata(metadataFile);
|
||||
return this.metadata;
|
||||
}
|
||||
protected JsonObject root;
|
||||
|
||||
protected Map<String, JsonMetadataSection> sections = null;
|
||||
|
||||
public FileResourceMetadata(File metadataFile) {
|
||||
super();
|
||||
this.metadataFile = metadataFile;
|
||||
if (this.metadataFile.exists()) {
|
||||
try {
|
||||
this.root = JSONUtils.getJsonRootObject(metadataFile.toURI().toURL());
|
||||
} catch (IOException e) {
|
||||
log.error("Error reading metadata from [" + this.metadataFile.getAbsolutePath() + "]", e);
|
||||
this.root = new JsonObject();
|
||||
}
|
||||
} else {
|
||||
this.root = new JsonObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean exists() {
|
||||
return metadataFile.exists();
|
||||
}
|
||||
|
||||
protected void initSections() {
|
||||
if (this.sections == null) {
|
||||
this.sections = new HashMap<>();
|
||||
for (Entry<String, JsonElement> entry : root.entrySet()) {
|
||||
if (entry.getValue().isJsonObject()) {
|
||||
sections.put(entry.getKey(),
|
||||
new JsonMetadataSection(entry.getKey(), entry.getValue().getAsJsonObject()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MetadataSection> getSections() {
|
||||
initSections();
|
||||
return this.sections.values().stream()
|
||||
.map(m -> (MetadataSection) m)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSection(String sectionName) {
|
||||
initSections();
|
||||
return this.sections.containsKey(sectionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataSection getSection(String sectionName) {
|
||||
if (!hasSection(sectionName)) {
|
||||
this.sections.put(sectionName, new JsonMetadataSection(sectionName, new JsonObject()));
|
||||
}
|
||||
return this.sections.get(sectionName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
for (JsonMetadataSection section : sections.values()) {
|
||||
JSONUtils.replaceValue(root, section.getName(), section.content);
|
||||
}
|
||||
try {
|
||||
FileUtils.string2file(root.toString(), metadataFile);
|
||||
} catch (IOException e) {
|
||||
log.error("Error saving file [" + metadataFile.getAbsolutePath() + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getAsJson() {
|
||||
JsonObject result = root.deepCopy();
|
||||
if (sections == null)
|
||||
initSections();
|
||||
for (JsonMetadataSection section : sections.values()) {
|
||||
JSONUtils.replaceValue(result, section.getName(), section.content);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FileResource extends AbstractResource<FileResourceMetadata> {
|
||||
|
||||
private File file;
|
||||
|
||||
private File metadataFile;
|
||||
|
||||
public FileResource(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteMatadata() {
|
||||
deleteFile(metadataFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void deleteResource() {
|
||||
deleteFile(file);
|
||||
}
|
||||
|
||||
protected void deleteFile(File f) {
|
||||
if (f == null)
|
||||
return;
|
||||
if (!f.exists())
|
||||
return;
|
||||
if (!f.isDirectory())
|
||||
f.delete();
|
||||
else
|
||||
try {
|
||||
org.apache.commons.io.FileUtils.deleteDirectory(f);
|
||||
} catch (IOException e) {
|
||||
log.error("Error deleting directory [" + f.toPath().toString() + "]", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() {
|
||||
if (!exists())
|
||||
return null;
|
||||
if (file.isDirectory())
|
||||
return null;
|
||||
try {
|
||||
return file.toURI().toURL().openStream();
|
||||
} catch (IOException e) {
|
||||
FileResourceProvider.log.error("Error getting resource", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
if (!exists())
|
||||
return null;
|
||||
if (file.isDirectory())
|
||||
return "";
|
||||
String result = null;
|
||||
try (InputStream is = getInputStream()) {
|
||||
result = IOUtils.toString(is);
|
||||
} catch (IOException e) {
|
||||
FileResourceProvider.log.error("Error getting resource as string", e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(InputStream inputStream) {
|
||||
if (!file.exists())
|
||||
try {
|
||||
log.debug("\nMAKE DIRS", file.getParentFile().getAbsolutePath());
|
||||
file.getParentFile().mkdirs();
|
||||
// file.createNewFile();
|
||||
} catch (Exception e1) {
|
||||
log.error("Error creating resource", e1);
|
||||
}
|
||||
if (file.isDirectory())
|
||||
return;
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
|
||||
FileChannel channel = fileOutputStream.getChannel();
|
||||
FileLock lock = channel.lock();
|
||||
byte[] bytes = IOUtils.toByteArray(inputStream);
|
||||
channel.write(ByteBuffer.wrap(bytes));
|
||||
|
||||
lock.release();
|
||||
channel.close();
|
||||
IOUtils.closeQuietly(fileOutputStream);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error saving resource", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getLocation() {
|
||||
try {
|
||||
return this.file.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFolder() {
|
||||
return file.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
try {
|
||||
if (file.isFile())
|
||||
return Files.size(file.toPath());
|
||||
return 0;
|
||||
} catch (IOException e) {
|
||||
log.warn("Error getting file size for [" + file.getAbsolutePath() + "]", e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doInitMetadata() {
|
||||
String metadataFileName = (file.isDirectory() ? "" : file.getName())
|
||||
+ "." + FileResourceProvider.METADATA_FILE_EXTENSION;
|
||||
Path metadataFilePath = Path.of(
|
||||
(file.isDirectory()
|
||||
? file
|
||||
: file.getParentFile()).toPath().toString(),
|
||||
metadataFileName);
|
||||
metadataFile = metadataFilePath.toFile();
|
||||
if (metadataFile.exists())
|
||||
this.metadata = new FileResourceMetadata(metadataFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FileResourceMetadata createMetadata() {
|
||||
if (!metadataFile.exists())
|
||||
this.metadata = new FileResourceMetadata(metadataFile);
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURL() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURL() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -37,27 +37,28 @@ import org.apache.karaf.shell.api.action.Argument;
|
||||
import org.apache.karaf.shell.api.action.Command;
|
||||
import org.apache.karaf.shell.api.action.lifecycle.Service;
|
||||
|
||||
import ru.entaxy.esb.resources.EntaxyResourceURLFactory;
|
||||
|
||||
@Service
|
||||
@Command (scope = "resources", name = "display")
|
||||
@Command(scope = "resources", name = "display")
|
||||
public class ResourceOpenByUrl implements Action {
|
||||
|
||||
@Argument (index = 0, name = "resourceUrl", required = true)
|
||||
String resourceUrl;
|
||||
|
||||
@Override
|
||||
public Object execute() throws Exception {
|
||||
URL url = new URL(resourceUrl);
|
||||
URLConnection connection = url.openConnection();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)))
|
||||
{
|
||||
String text = reader.lines().collect(Collectors.joining("\n"));
|
||||
System.out.println(text);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error executing command");
|
||||
System.out.println(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Argument(index = 0, name = "resourceUrl", required = true)
|
||||
String resourceUrl;
|
||||
|
||||
@Override
|
||||
public Object execute() throws Exception {
|
||||
URL url = EntaxyResourceURLFactory.getGlobalUrl(resourceUrl);
|
||||
URLConnection connection = url.openConnection();
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
String text = reader.lines().collect(Collectors.joining("\n"));
|
||||
System.out.println(text);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error executing command");
|
||||
System.out.println(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* schema-impl
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -25,24 +25,26 @@
|
||||
*/
|
||||
package ru.entaxy.esb.resources.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.url.URLStreamHandlerService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import ru.entaxy.platform.base.support.CommonUtils;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.URIResolver;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@Component(service = URIResolver.class, property = "type=xslt", immediate = true)
|
||||
@Component(service = URIResolver.class, property = {"type=xslt", "provider=entaxy-resources"}, immediate = true)
|
||||
public class XslUrlResolver implements URIResolver {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(XslUrlResolver.class);
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
@ -40,70 +40,74 @@ import ru.entaxy.platform.base.support.CommonUtils;
|
||||
|
||||
public class ResourceProvider {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ResourceProvider.class);
|
||||
|
||||
public static final String RESOURCE_PATH = "/ru/entaxy/resource";
|
||||
|
||||
protected Bundle bundle;
|
||||
|
||||
protected Map<String, List<ResourceDescriptor>> resources = new HashMap<>();
|
||||
|
||||
public ResourceProvider(Bundle bundle) {
|
||||
this.bundle = bundle;
|
||||
}
|
||||
|
||||
public Map<String, List<ResourceDescriptor>> getResources(){
|
||||
if (!resources.isEmpty())
|
||||
return resources;
|
||||
|
||||
Enumeration<URL> foundEntries = bundle.findEntries(ResourceProvider.RESOURCE_PATH, "*.*", true);
|
||||
while (foundEntries.hasMoreElements()) {
|
||||
URL entry = foundEntries.nextElement();
|
||||
log.debug("FOUND :: " + entry.toString());
|
||||
if (entry.toString().endsWith("/")) {
|
||||
log.debug(":: .. is folder");
|
||||
continue;
|
||||
}
|
||||
String localPath = entry.toString();
|
||||
localPath = localPath.substring(localPath.indexOf(ResourceProvider.RESOURCE_PATH) + ResourceProvider.RESOURCE_PATH.length() + 1);
|
||||
|
||||
String resourceName = localPath.substring(localPath.lastIndexOf("/")+1);
|
||||
|
||||
String path = localPath.lastIndexOf("/")>=0
|
||||
?localPath.substring(0, localPath.lastIndexOf("/"))
|
||||
:"";
|
||||
int splitIndex = path.indexOf("/");
|
||||
String protocol = splitIndex>0
|
||||
?path.substring(0, splitIndex)
|
||||
:"";
|
||||
|
||||
if (splitIndex>0)
|
||||
path = path.substring(splitIndex+1);
|
||||
|
||||
if (!CommonUtils.isValid(protocol) || !CommonUtils.isValid(resourceName))
|
||||
continue;
|
||||
|
||||
if (!resources.containsKey(protocol))
|
||||
resources.put(protocol, new ArrayList<>());
|
||||
|
||||
resources.get(protocol).add(new ResourceDescriptor(entry, path + "/" + resourceName));
|
||||
|
||||
}
|
||||
|
||||
return resources;
|
||||
|
||||
}
|
||||
|
||||
public static class ResourceDescriptor {
|
||||
|
||||
public URL url;
|
||||
public String location;
|
||||
|
||||
public ResourceDescriptor(URL url, String location) {
|
||||
this.url = url;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ResourceProvider.class);
|
||||
|
||||
public static final String RESOURCE_PATH = "/ru/entaxy/resource";
|
||||
|
||||
protected Bundle bundle;
|
||||
|
||||
protected Map<String, List<ResourceDescriptor>> resources = new HashMap<>();
|
||||
|
||||
public ResourceProvider(Bundle bundle) {
|
||||
this.bundle = bundle;
|
||||
}
|
||||
|
||||
public Map<String, List<ResourceDescriptor>> getResources() {
|
||||
if (!resources.isEmpty())
|
||||
return resources;
|
||||
|
||||
Enumeration<URL> foundEntries = bundle.findEntries(ResourceProvider.RESOURCE_PATH, "*.*", true);
|
||||
if (foundEntries == null)
|
||||
return resources;
|
||||
|
||||
while (foundEntries.hasMoreElements()) {
|
||||
URL entry = foundEntries.nextElement();
|
||||
log.debug("FOUND :: " + entry.toString());
|
||||
if (entry.toString().endsWith("/")) {
|
||||
log.debug(":: .. is folder");
|
||||
continue;
|
||||
}
|
||||
String localPath = entry.toString();
|
||||
localPath = localPath.substring(
|
||||
localPath.indexOf(ResourceProvider.RESOURCE_PATH) + ResourceProvider.RESOURCE_PATH.length() + 1);
|
||||
|
||||
String resourceName = localPath.substring(localPath.lastIndexOf("/") + 1);
|
||||
|
||||
String path = localPath.lastIndexOf("/") >= 0
|
||||
? localPath.substring(0, localPath.lastIndexOf("/"))
|
||||
: "";
|
||||
int splitIndex = path.indexOf("/");
|
||||
String protocol = splitIndex > 0
|
||||
? path.substring(0, splitIndex)
|
||||
: "";
|
||||
|
||||
if (splitIndex > 0)
|
||||
path = path.substring(splitIndex + 1);
|
||||
|
||||
if (!CommonUtils.isValid(protocol) || !CommonUtils.isValid(resourceName))
|
||||
continue;
|
||||
|
||||
if (!resources.containsKey(protocol))
|
||||
resources.put(protocol, new ArrayList<>());
|
||||
|
||||
resources.get(protocol).add(new ResourceDescriptor(entry, path + "/" + resourceName));
|
||||
|
||||
}
|
||||
|
||||
return resources;
|
||||
|
||||
}
|
||||
|
||||
public static class ResourceDescriptor {
|
||||
|
||||
public URL url;
|
||||
public String location;
|
||||
|
||||
public ResourceDescriptor(URL url, String location) {
|
||||
this.url = url;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ~~~~~~licensing~~~~~~
|
||||
* resources-service
|
||||
* ==========
|
||||
* Copyright (C) 2020 - 2023 EmDev LLC
|
||||
* Copyright (C) 2020 - 2024 EmDev LLC
|
||||
* ==========
|
||||
* You may not use this file except in accordance with the License Terms of the Copyright
|
||||
* Holder located at: https://entaxy.ru/eula . All copyrights, all intellectual property
|
||||
|
Reference in New Issue
Block a user