diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/NLocationKey.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/NLocationKey.java new file mode 100644 index 000000000..d505da39d --- /dev/null +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/NLocationKey.java @@ -0,0 +1,78 @@ +package net.thevpc.nuts.runtime.standalone; + +import net.thevpc.nuts.NId; +import net.thevpc.nuts.NStoreType; +import net.thevpc.nuts.util.NAssert; +import net.thevpc.nuts.util.NBlankable; +import net.thevpc.nuts.util.NStringUtils; + +import java.util.Objects; + +public class NLocationKey { + private String name; + private NId id; + private String repoUuid; + private NStoreType storeType; + + public static NLocationKey of(NStoreType storeType,NId id,String name) { + return new NLocationKey(storeType, id, name, null); + } + public static NLocationKey of(NStoreType storeType,NId id,String name, String repoUuid) { + return new NLocationKey(storeType, id, name, repoUuid); + } + public static NLocationKey ofCache(NId id,String name, String repoUuid) { + return new NLocationKey(NStoreType.CACHE, id, name, repoUuid); + } + + public NLocationKey(NStoreType storeType, NId id, String name, String repoUuid) { + if(NBlankable.isBlank(name)){ + this.name = null; + }else { + NAssert.requireTrue(name.matches("[a-zA-Z0-9._-]"), "name matches [a-zA-Z0-9._-]"); + this.name = name; + } + this.id = NAssert.requireNonBlank(id, "id"); + this.storeType = NAssert.requireNonNull(storeType, "storeType"); + this.repoUuid = NStringUtils.trimToNull(repoUuid); + } + + + public String getName() { + return name; + } + + public NId getId() { + return id; + } + + public String getRepoUuid() { + return repoUuid; + } + + public NStoreType getStoreType() { + return storeType; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + NLocationKey that = (NLocationKey) o; + return Objects.equals(name, that.name) && Objects.equals(id, that.id) && Objects.equals(repoUuid, that.repoUuid) && storeType == that.storeType; + } + + @Override + public int hashCode() { + return Objects.hash(name, id, repoUuid, storeType); + } + + @Override + public String toString() { + return "NLocationKey{" + + "name='" + name + '\'' + + ", id=" + id + + ", repoUuid='" + repoUuid + '\'' + + ", storeType=" + storeType + + '}'; + } +} diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/NWsConfDB.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/NWsConfDB.java new file mode 100644 index 000000000..6d1666d1a --- /dev/null +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/NWsConfDB.java @@ -0,0 +1,24 @@ +package net.thevpc.nuts.runtime.standalone; + +import net.thevpc.nuts.NLocations; +import net.thevpc.nuts.NSession; +import net.thevpc.nuts.io.NPath; +import net.thevpc.nuts.util.NBlankable; + +public class NWsConfDB { + public void storeStringNonBlank(NLocationKey k, String value, NSession session) { + storeString(k, value, true, session); + } + + public void storeString(NLocationKey k, String value, boolean deleteIfBlank, NSession session) { + NPath path = NLocations.of(session).getStoreLocation(k.getId(), k.getStoreType(), k.getRepoUuid()) + .resolve(k.getName()); + if (NBlankable.isBlank(value) && deleteIfBlank) { + if (path.isRegularFile()) { + path.delete(); + } + } else { + path.writeString(value); + } + } +} diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/definition/DefaultNDefinition.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/definition/DefaultNDefinition.java index 5926805ab..99c8fd476 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/definition/DefaultNDefinition.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/definition/DefaultNDefinition.java @@ -50,7 +50,9 @@ public class DefaultNDefinition implements NDefinition { public DefaultNDefinition() { } - public DefaultNDefinition(String repoUuid, String repoName, NId id, NDescriptor descriptor, NPath content, NInstallInformation install, NId apiId, NSession session) { + public DefaultNDefinition(String repoUuid, String repoName, NId id, NDescriptor descriptor, NPath content, NInstallInformation install, NId apiId, + NDescriptor effectiveDescriptor, + NSession session) { this.descriptor = descriptor; this.content = content; this.id = id; @@ -60,6 +62,7 @@ public DefaultNDefinition(String repoUuid, String repoName, NId id, NDescriptor this.installInformation = install; this.repositoryUuid = repoUuid; this.repositoryName = repoName; + this.effectiveDescriptor = effectiveDescriptor; this.apiId = apiId; this.session = session; } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/definition/DefaultNDefinitionRef.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/definition/DefaultNDefinitionRef.java new file mode 100755 index 000000000..1c2f3aa63 --- /dev/null +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/definition/DefaultNDefinitionRef.java @@ -0,0 +1,190 @@ +/** + * ==================================================================== + * Nuts : Network Updatable Things Service + * (universal package manager) + *
+ * is a new Open Source Package Manager to help install packages and libraries + * for runtime execution. Nuts is the ultimate companion for maven (and other + * build managers) as it helps installing all package dependencies at runtime. + * Nuts is not tied to java and is a good choice to share shell scripts and + * other 'things' . Its based on an extensible architecture to help supporting a + * large range of sub managers / repositories. + *
+ *

+ * Copyright [2020] [thevpc] Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law + * or agreed to in writing, software distributed under the License is + * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + *
==================================================================== + */ +package net.thevpc.nuts.runtime.standalone.definition; + +import net.thevpc.nuts.*; +import net.thevpc.nuts.io.NPath; +import net.thevpc.nuts.runtime.standalone.io.cache.CachedSupplier; +import net.thevpc.nuts.util.NAssert; +import net.thevpc.nuts.util.NMsg; +import net.thevpc.nuts.util.NOptional; + +import java.util.Objects; +import java.util.function.Supplier; + +/** + * Created by vpc on 1/6/17. + */ +public class DefaultNDefinitionRef implements NDefinition { + + private NId id; + private CachedSupplier descriptor; + private CachedSupplier repositoryUuid; + private CachedSupplier repositoryName; + + private CachedSupplier content; + private CachedSupplier installInformation; + private CachedSupplier dependencies; + private CachedSupplier effectiveDescriptor; + private CachedSupplier apiId = null; + private transient NSession session; + + public DefaultNDefinitionRef() { + } + + public DefaultNDefinitionRef(CachedSupplier repositoryUuid, CachedSupplier repositoryName, NId id, CachedSupplier descriptor, CachedSupplier content, + CachedSupplier install, + CachedSupplier apiId, + CachedSupplier dependencies, + CachedSupplier effectiveDescriptor, + NSession session) { + this.descriptor = NAssert.requireNonNull(descriptor, "descriptor", session); + this.content = NAssert.requireNonNull(content, "content", session); + this.id = NAssert.requireNonNull(id, "id", session); + if (!id.isLongId()) { + throw new NIllegalArgumentException(session, NMsg.ofC("id should not have query defined in descriptors : %s", id)); + } + this.installInformation = NAssert.requireNonNull(install, "installInformation", session); + this.repositoryUuid = NAssert.requireNonNull(repositoryUuid, "repositoryUuid", session); + this.repositoryName = NAssert.requireNonNull(repositoryName, "repositoryName", session); + this.dependencies = NAssert.requireNonNull(dependencies, "dependencies", session); + this.effectiveDescriptor = NAssert.requireNonNull(effectiveDescriptor, "effectiveDescriptor", session); + this.apiId = NAssert.requireNonNull(apiId, "apiId", session); + this.session = session; + } + + @Override + public String getRepositoryUuid() { + return repositoryUuid.getValue(); + } + + @Override + public String getRepositoryName() { + return repositoryName.getValue(); + } + + @Override + public NId getId() { + return id; + } + + public boolean isTemporary() { + NPath c = content.getValue(); + return c != null && c.isUserTemporary(); + } + + public NDescriptor getDescriptor() { + return descriptor.getValue(); + } + + @Override + public String toString() { + return "Definition{" + + " id=" + id + + ", content=" + content + + '}'; + } + + public DefaultNDefinition copy() { + return new DefaultNDefinition(this, session); + } + + @Override + public NOptional getContent() { + NPath c = content.getValue(); + return NOptional.of(c, s -> NMsg.ofC("content not found for id %s", getId())) + .setSession(session); + } + + @Override + public NOptional getEffectiveDescriptor() { + NDescriptor c = effectiveDescriptor.getValue(); + return NOptional.of(c, s -> NMsg.ofC("unable to get effectiveDescriptor for id %s. You need to call search.setEffective(...) first.", getId())) + .setSession(session); + } + + @Override + public NOptional getInstallInformation() { + return NOptional.of(installInformation.getValue(), s -> NMsg.ofC("unable to get install information for id %s.", getId())) + .setSession(session); + } + + @Override + public NOptional getDependencies() { + return NOptional.of(dependencies.getValue(), s -> NMsg.ofC("unable to get dependencies for id %s. You need to call search.setDependencies(...) first.", getId())) + .setSession(session); + } + + @Override + public int compareTo(NDefinition n2) { + if (n2 == null) { + return 1; + } + if (!(n2 instanceof DefaultNDefinitionRef)) { + return -1; + } + NId o1 = getId(); + NId o2 = n2.getId(); + if (o1 == null || o2 == null) { + if (o1 == o2) { + return 0; + } + if (o1 == null) { + return -1; + } + return 1; + } + return o1.compareTo(o2); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 37 * hash + Objects.hashCode(this.id); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final DefaultNDefinitionRef other = (DefaultNDefinitionRef) obj; + if (!Objects.equals(this.id, other.id)) { + return false; + } + return true; + } + + @Override + public NId getApiId() { + return apiId.getValue(); + } +} diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/elem/mapper/NElementMapperNDefinition.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/elem/mapper/NElementMapperNDefinition.java index 77e755559..565cfd741 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/elem/mapper/NElementMapperNDefinition.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/elem/mapper/NElementMapperNDefinition.java @@ -25,7 +25,7 @@ public NElement createElement(NDefinition o, Type typeOfSrc, NElementFactoryCont @Override public NDefinition createObject(NElement o, Type typeOfResult, NElementFactoryContext context) { NDefinition d = context.defaultElementToObject(o, DefaultNDefinition.class); - //pass the session the the instance + //pass the session the instance return new DefaultNDefinition(d, context.getSession()); } } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/executor/system/ProcessExecHelper.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/executor/system/ProcessExecHelper.java index 1eba14655..33679604e 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/executor/system/ProcessExecHelper.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/executor/system/ProcessExecHelper.java @@ -96,9 +96,9 @@ public static ProcessExecHelper ofDefinition(NDefinition nutMainFile, NPath storeFolder = nutMainFile.getInstallInformation().get(session).getInstallFolder(); HashMap map = new HashMap<>(); HashMap envmap = new HashMap<>(); - Path nutsJarFile = NFetchCommand.ofNutsApi(session).getResultPath(); + NPath nutsJarFile = NFetchCommand.ofNutsApi(session).getResultPath(); if (nutsJarFile != null) { - map.put("nuts.jar", nutsJarFile.toAbsolutePath().normalize().toString()); + map.put("nuts.jar", nutsJarFile.normalize().toString()); } map.put("nuts.artifact", id.toString()); map.put("nuts.file", nutMainFile.getContent().flatMap(NPath::toPath).map(Object::toString).orNull()); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/cache/CachedSupplier.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/cache/CachedSupplier.java new file mode 100644 index 000000000..7e8f2a239 --- /dev/null +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/cache/CachedSupplier.java @@ -0,0 +1,13 @@ +package net.thevpc.nuts.runtime.standalone.io.cache; + + +public interface CachedSupplier { + enum NCacheLevel { + NONE, + MEM, + STORE + } + + T getValue(); + T getValue(NCacheLevel level); +} diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/cache/DefaultCachedSupplier.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/cache/DefaultCachedSupplier.java new file mode 100644 index 000000000..ffaf5db10 --- /dev/null +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/cache/DefaultCachedSupplier.java @@ -0,0 +1,269 @@ +package net.thevpc.nuts.runtime.standalone.io.cache; + +import net.thevpc.nuts.NLocations; +import net.thevpc.nuts.NSession; +import net.thevpc.nuts.NStoreType; +import net.thevpc.nuts.elem.NElements; +import net.thevpc.nuts.io.NPath; +import net.thevpc.nuts.runtime.standalone.NLocationKey; +import net.thevpc.nuts.runtime.standalone.io.util.CoreIOUtils; +import net.thevpc.nuts.runtime.standalone.workspace.NWorkspaceExt; +import net.thevpc.nuts.util.NBlankable; + +import java.util.Objects; +import java.util.function.Supplier; + +public class DefaultCachedSupplier implements CachedSupplier { + private final Supplier supplier; + private T value; + private String valueCacheId; + private boolean evaluated; + private RuntimeException exception; + private final NSession session; + private final Class clazz; + private final CacheValidator validator; + private NElements elems; + private NPath cachePath; + private NPath cacheIdPath; + private NCacheLevel level; + private NLocationKey key; + + + public static DefaultCachedSupplier ofMem(Supplier supplier, CacheValidator validator) { + return new DefaultCachedSupplier<>( + NCacheLevel.MEM, + (Class) Object.class, + null, supplier, validator, null + ); + } + + public static DefaultCachedSupplier ofNone(Supplier supplier) { + return new DefaultCachedSupplier<>( + NCacheLevel.NONE, + (Class) Object.class, + null, supplier, null, null + ); + } + + public static DefaultCachedSupplier ofStore(Class clazz, + NLocationKey key, Supplier supplier, CacheValidator validator, NSession session) { + return new DefaultCachedSupplier<>(NCacheLevel.STORE, + clazz, + key, supplier, validator, session + ); + } + + public static DefaultCachedSupplier of(NCacheLevel level, + Class clazz, + NLocationKey key, Supplier supplier, CacheValidator validator, NSession session) { + return new DefaultCachedSupplier<>(level, + clazz, + key, supplier, validator, session + ); + } + + public DefaultCachedSupplier(NCacheLevel level, + Class clazz, + NLocationKey key, Supplier supplier, CacheValidator validator, NSession session) { + this.session = session; + this.level = level; + this.key = key; + this.clazz = clazz; + this.validator = validator; + this.supplier = supplier; + if (this.level.ordinal() >= NCacheLevel.STORE.ordinal()) { + if (key.getStoreType() != NStoreType.CACHE) { + throw new IllegalArgumentException("expected cache store"); + } + NLocations nLocations = NLocations.of(session); + this.elems = NElements.of(session); + this.cachePath = nLocations.getStoreLocation(key.getId(), key.getStoreType(), key.getRepoUuid()) + .resolve(nLocations.getDefaultIdFilename(key.getId().builder().setFace(key.getName() + ".value.cache").build())); + this.cacheIdPath = nLocations.getStoreLocation(key.getId(), key.getStoreType(), key.getRepoUuid()) + .resolve(nLocations.getDefaultIdFilename(key.getId().builder().setFace(key.getName() + ".id.cache").build())); + } + } + + @Override + public T getValue() { + return getValue(level); + } + + @Override + public T getValue(NCacheLevel level) { + if (level == null) { + level = this.level; + } + if (level.ordinal() > this.level.ordinal()) { + level = this.level; + } + switch (level) { + case NONE: + return getNoCacheValue(); + case MEM: + return getMemValue(); + case STORE: + return getFileValue(); + } + throw new IllegalArgumentException("unsupported"); + } + + private T getNoCacheValue() { + return supplier.get(); + } + + + private String loadCachedId() { + try { + if (cachePath.isRegularFile()) { + return cacheIdPath.readString().trim(); + } + } catch (Exception ex) { + //just ignore + } + return null; + } + + private T getFileValue() { + String currentCacheId = null; + if (validator != null) { + currentCacheId = validator.getCacheId(); + if (!NBlankable.isBlank(currentCacheId) && !validator.isValidCacheId(valueCacheId)) { + evaluated = false; + } + } + if (!evaluated) { + //check file + if (currentCacheId != null) { + String loadCacheId = loadCachedId(); + if (validator == null || validator.isValidCacheId(loadCacheId)) { + if (CoreIOUtils.isObsoletePath(session, cachePath)) { + //this is invalid cache! + if(cachePath.isRegularFile()) { + cachePath.delete(); + } + } else { + try { + T d = elems.json().parse(cachePath, clazz); + if (d != null) { + if (validator != null && !validator.isValidValue(d)) { + //this is invalid cache! + if(cachePath.isRegularFile()) { + cachePath.delete(); + } + } + this.valueCacheId = currentCacheId; + this.value = d; + return d; + } + } catch (Exception ex) { + // + } + } + } + } + + if (supplier == null) { + value = null; + valueCacheId = null; + cachePath.delete(); + cacheIdPath.delete(); + } else { + valueCacheId = null; + value = null; + try { + value = getNoCacheValue(); + valueCacheId = currentCacheId; + } catch (RuntimeException ex) { + exception = ex; + } catch (Exception ex) { + exception = new RuntimeException(ex); + } + if (value != null) { + try { + elems.json().setValue(value).setNtf(false).print(cachePath); + } catch (Exception ex) { + // + } + } else { + if(cachePath.isRegularFile()) { + cachePath.delete(); + } + } + } + evaluated = true; + } + if (exception != null) { + throw exception; + } + return value; + } + + private T getMemValue() { + String currentCacheId = null; + if (validator != null) { + currentCacheId = validator.getCacheId(); + if (!NBlankable.isBlank(currentCacheId) || !validator.isValidCacheId(currentCacheId)) { + evaluated = false; + } + } + if (!evaluated) { + if (supplier == null) { + value = null; + valueCacheId = null; + } else { + valueCacheId = null; + try { + value = getNoCacheValue(); + valueCacheId = currentCacheId; + } catch (RuntimeException ex) { + exception = ex; + } catch (Exception ex) { + exception = new RuntimeException(ex); + } + } + evaluated = true; + } + if (exception != null) { + throw exception; + } + return value; + } + + public static class SimpleCacheValidator implements CacheValidator { + NSession session; + + public SimpleCacheValidator(NSession session) { + this.session=session; + } + + @Override + public String getCacheId() { + return NWorkspaceExt.of(session).getModel().installationDigest; + } + + @Override + public boolean isValidCacheId(String cacheId) { + String id = getCacheId(); + return NBlankable.isBlank(id) || Objects.equals(cacheId, id); + } + + @Override + public boolean isValidValue(T value) { + return true; + } + } + + public interface CacheValidator { + String getCacheId(); + + default boolean isValidCacheId(String cacheId) { + String id = getCacheId(); + return NBlankable.isBlank(id) || Objects.equals(cacheId, id); + } + + boolean isValidValue(T value); + } + + +} diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/inputstream/DefaultNIO.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/inputstream/DefaultNIO.java index 6c49b0655..f5c82e837 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/inputstream/DefaultNIO.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/inputstream/DefaultNIO.java @@ -106,8 +106,8 @@ public NPrintStream ofPrintStream(OutputStream out, NTerminalMode expectedMode, return ((NPrintStreamAdapter) out).getBasePrintStream().setTerminalMode(expectedMode); } return - new NPrintStreamRaw(out, null, null, session, new NPrintStreamBase.Bindings(), term) - .setTerminalMode(expectedMode) + new NPrintStreamRaw(out,expectedMode, null, null, session, new NPrintStreamBase.Bindings(), term) +// .setTerminalMode(expectedMode) ; } @@ -120,6 +120,16 @@ public NPrintStream ofPrintStream(OutputStream out) { return new NPrintStreamRaw(out, null, null, session, new NPrintStreamBase.Bindings(), null); } + @Override + public NPrintStream ofPrintStream(Writer out, NTerminalMode mode) { + return ofPrintStream(out,mode,null); + } + + @Override + public NPrintStream ofPrintStream(OutputStream out, NTerminalMode mode) { + return ofPrintStream(out,mode,null); + } + public NPrintStream ofPrintStream(Writer out, NTerminalMode mode, NSystemTerminalBase terminal) { checkSession(); if (mode == null) { diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/AnsiNPrintStreamTerminalBase.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/AnsiNPrintStreamTerminalBase.java index 856144cf7..d0cd6574c 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/AnsiNPrintStreamTerminalBase.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/AnsiNPrintStreamTerminalBase.java @@ -13,7 +13,7 @@ import java.io.InputStream; -class AnsiNPrintStreamTerminalBase extends NSystemTerminalBaseImpl { +public class AnsiNPrintStreamTerminalBase extends NSystemTerminalBaseImpl { private NPrintStream out; private NCmdLineHistory history; private String commandHighlighter; diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NByteArrayPrintStream.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NByteArrayPrintStream.java index 671e2c4b8..125321156 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NByteArrayPrintStream.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NByteArrayPrintStream.java @@ -16,9 +16,6 @@ public class NByteArrayPrintStream extends NPrintStreamRaw implements NMemoryPri public NByteArrayPrintStream(NTerminalMode mode, NSession session) { super(new ByteArrayOutputStream2(), mode, null, null, session, new Bindings(), null); - if (mode == NTerminalMode.ANSI) { - this.term = new AnsiNPrintStreamTerminalBase(this); - } getMetaData().setMessage( NMsg.ofNtf(NTexts.of(session).ofStyled("", NTextStyle.path())) ); @@ -26,9 +23,6 @@ public NByteArrayPrintStream(NTerminalMode mode, NSession session) { protected NByteArrayPrintStream(NTerminalMode mode, ByteArrayOutputStream2 bos, NSession session) { super(bos, mode, null, null, session, new Bindings(), null); - if (mode == NTerminalMode.ANSI) { - this.term = new AnsiNPrintStreamTerminalBase(this); - } getMetaData().setMessage( NMsg.ofNtf(NTexts.of(session).ofStyled("", NTextStyle.path())) ); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamBase.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamBase.java index 36c8cd637..245fe4632 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamBase.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamBase.java @@ -29,10 +29,14 @@ public abstract class NPrintStreamBase implements NPrintStream { public NPrintStreamBase(boolean autoFlash, NTerminalMode mode, NSession session, Bindings bindings, NSystemTerminalBase term) { NAssert.requireNonNull(mode, "mode", session); + bindings.setOrErr(this, mode); this.bindings = bindings; this.autoFlash = autoFlash; this.mode = mode; this.session = session; + if(term==null && mode==NTerminalMode.ANSI){ + term=new AnsiNPrintStreamTerminalBase(this); + } this.term = term; } @@ -398,33 +402,11 @@ public NPrintStream setTerminalMode(NTerminalMode other) { if (other == null || other == this.getTerminalMode()) { return this; } - switch (other) { - case ANSI: { - if (bindings.ansi != null) { - return bindings.filtered; - } - return convertImpl(other); - } - case INHERITED: { - if (bindings.inherited != null) { - return bindings.inherited; - } - return convertImpl(other); - } - case FORMATTED: { - if (bindings.formatted != null) { - return bindings.formatted; - } - return convertImpl(other); - } - case FILTERED: { - if (bindings.filtered != null) { - return bindings.filtered; - } - return convertImpl(other); - } + NPrintStreamBase o = bindings.get(other); + if (o != null) { + return o; } - throw new IllegalArgumentException("unsupported yet"); + return convertImpl(other); } @Override @@ -472,6 +454,126 @@ public static class Bindings { protected NPrintStreamBase ansi; protected NPrintStreamBase inherited; protected NPrintStreamBase formatted; + + public void set(NPrintStreamBase o, NTerminalMode mode) { + NAssert.requireNonNull(o, "terminal"); + NAssert.requireNonNull(mode, "mode"); + switch (mode) { + case ANSI: { + this.ansi = o; + if (this.raw == null) { + this.raw = this.ansi; + } + break; + } + case FILTERED: { + this.filtered = o; + break; + } + case FORMATTED: { + this.formatted = o; + break; + } + case INHERITED: { + this.inherited = o; + if (this.raw == null) { + this.raw = this.ansi; + } + break; + } + case DEFAULT: { + this.raw = o; + break; + } + } + } + + public NPrintStreamBase get(NTerminalMode mode) { + NAssert.requireNonNull(mode, "mode"); + switch (mode) { + case FILTERED: + return this.filtered; + case ANSI: + return this.ansi; + case FORMATTED: + return this.formatted; + case INHERITED: + return this.inherited; + case DEFAULT: + return this.raw; + } + throw new IllegalArgumentException("unexpected"); + } + + public void setOrErr(NPrintStreamBase o, NTerminalMode mode) { + setIfNull(o,mode,true); + } + + public void setIfNull(NPrintStreamBase o, NTerminalMode mode, boolean err) { + NAssert.requireNonNull(o, "terminal"); + NAssert.requireNonNull(mode, "mode"); + switch (mode) { + case ANSI: { + if (this.ansi == null) { + this.ansi = o; + if (this.raw == null) { + this.raw = this.ansi; + } + } else { + if (err) { + throw new IllegalArgumentException("already bound " + mode); + } + } + break; + } + case FILTERED: { + if (this.filtered == null) { + this.filtered = o; + } else { + if (err) { + throw new IllegalArgumentException("already bound " + mode); + } + } + break; + } + case FORMATTED: { + if (this.formatted == null) { + this.formatted = o; + } else { + if (err) { + throw new IllegalArgumentException("already bound " + mode); + } + } + break; + } + case INHERITED: { + if (this.inherited == null) { + this.inherited = o; + if (this.ansi == null) { + this.ansi = o; + } + if (this.raw == null) { + this.raw = this.ansi; + } + } else { + if (err) { + throw new IllegalArgumentException("already bound " + mode); + } + } + break; + } + case DEFAULT: { + if (this.raw == null) { + this.raw = o; + }else { + if (err) { + throw new IllegalArgumentException("already bound " + mode); + } + } + break; + } + } + } } @Override diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFiltered.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFiltered.java index ca98c255c..07ccb09b2 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFiltered.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFiltered.java @@ -13,13 +13,7 @@ public class NPrintStreamFiltered extends NPrintStreamRendered { public NPrintStreamFiltered(NPrintStreamBase base, NSession session, Bindings bindings) { super(base, session, NTerminalMode.FILTERED, bindings); - getMetaData().setMessage( - NMsg.ofStyled( "", NTextStyle.path()) - ); - if (bindings.filtered != null) { - throw new IllegalArgumentException("already bound ansi"); - } - bindings.filtered = this; + getMetaData().setMessage(NMsg.ofStyled( "", NTextStyle.path())); } @Override diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFormatted.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFormatted.java index 4efdea580..2244a218f 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFormatted.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamFormatted.java @@ -12,16 +12,8 @@ public class NPrintStreamFormatted extends NPrintStreamRendered { public NPrintStreamFormatted(NPrintStreamBase base, NSession session, Bindings bindings) { - super(base, session, NTerminalMode.FORMATTED, - bindings); - if (bindings.formatted != null) { - throw new NIllegalArgumentException(session, NMsg.ofPlain("formatted already bound")); - } - getMetaData().setMessage( - NMsg.ofStyled( - "", NTextStyle.path()) - ); - bindings.formatted = this; + super(base, session, NTerminalMode.FORMATTED, bindings); + getMetaData().setMessage(NMsg.ofStyled("", NTextStyle.path())); } @Override diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamRaw.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamRaw.java index 58abf47a8..99da046ca 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamRaw.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamRaw.java @@ -31,7 +31,10 @@ public NPrintStreamRaw(OutputStream out, Boolean autoFlush, String encoding, NSe this(out, null, autoFlush, encoding, session, bindings, term); } - public NPrintStreamRaw(OutputStream out, NTerminalMode mode, Boolean autoFlush, String encoding, NSession session, Bindings bindings, NSystemTerminalBase term) { + public NPrintStreamRaw(OutputStream out, NTerminalMode mode, Boolean autoFlush, + String encoding, NSession session, + Bindings bindings, + NSystemTerminalBase term) { super(true, mode == null ? NTerminalMode.INHERITED : mode, session, bindings, term); getMetaData().setMessage(NMsg.ofNtf(NTexts.of(session).ofStyled("", NTextStyle.path()))); this.out = out; @@ -51,25 +54,28 @@ public NPrintStreamRaw(OutputStream out, NTerminalMode mode, Boolean autoFlush, throw new IllegalArgumentException(e); } } - switch (getTerminalMode()) { - case ANSI: { - if (bindings.ansi != null) { - throw new IllegalArgumentException("already bound ansi"); - } - bindings.ansi = this; - if (bindings.inherited == null) { - bindings.inherited = this; - } - break; - } - case INHERITED: { - if (bindings.inherited != null) { - throw new IllegalArgumentException("already bound ansi"); - } - bindings.inherited = this; - break; - } - } +// switch (getTerminalMode()) { +// case ANSI: { +// if (bindings.ansi != null) { +// throw new IllegalArgumentException("already bound ansi"); +// } +// bindings.ansi = this; +// if (bindings.inherited == null) { +// bindings.inherited = this; +// } +// if (bindings.raw == null) { +// bindings.raw = this; +// } +// break; +// } +// case INHERITED: { +// if (bindings.inherited != null) { +// throw new IllegalArgumentException("already bound ansi"); +// } +// bindings.inherited = this; +// break; +// } +// } } public PrintStream getBase() { diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamSystem.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamSystem.java index 727743826..8fbd452fb 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamSystem.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/printstream/NPrintStreamSystem.java @@ -53,25 +53,25 @@ public NPrintStreamSystem(OutputStream out, Boolean autoFlush, String encoding, throw new IllegalArgumentException(e); } } - switch (getTerminalMode()) { - case ANSI: { - if (bindings.ansi != null) { - throw new IllegalArgumentException("already bound ansi"); - } - bindings.ansi = this; - if (bindings.inherited == null) { - bindings.inherited = this; - } - break; - } - case INHERITED: { - if (bindings.inherited != null) { - throw new IllegalArgumentException("already bound ansi"); - } - bindings.inherited = this; - break; - } - } +// switch (getTerminalMode()) { +// case ANSI: { +// if (bindings.ansi != null) { +// throw new IllegalArgumentException("already bound ansi"); +// } +// bindings.ansi = this; +// if (bindings.inherited == null) { +// bindings.inherited = this; +// } +// break; +// } +// case INHERITED: { +// if (bindings.inherited != null) { +// throw new IllegalArgumentException("already bound ansi"); +// } +// bindings.inherited = this; +// break; +// } +// } } private static NTerminalMode resolveMode(OutputStream out, Boolean ansi, NSession session) { diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/terminal/CoreAnsiTermHelper.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/terminal/CoreAnsiTermHelper.java index 714429612..d23eb01c6 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/terminal/CoreAnsiTermHelper.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/io/terminal/CoreAnsiTermHelper.java @@ -5,15 +5,18 @@ import net.thevpc.nuts.util.NLiteral; public class CoreAnsiTermHelper { + public static String tput(String str,long timeout,NSession session) { + return NExecCommand.of(session) + .system() + .addCommand("tput", str) + .failFast() + .getGrabbedOutOnlyString() + .trim() + ; + } public static boolean isXTerm(NSession session) { try { - String str = "cols"; - NExecCommand.of(session) - .system() - .addCommand("tput", str) - .failFast() - .getGrabbedOutOnlyString() - ; + tput("cols",0,session); return true; } catch (Exception ex) { return false; @@ -39,19 +42,12 @@ public static NSystemTerminalBase.Cursor evalCursor(NSession session) { public static String evalCapability(String str, NSession session) { try { - String d = NExecCommand.of(session).system() - .addCommand("tput", str) - .getGrabbedOutOnlyString(); - String s = d.trim(); + String s = tput(str,0,session); if (s.isEmpty()) { return null; } //add 500 of sleep time! - d = NExecCommand.of(session).system() - .addCommand("tput", str) - .setSleepMillis(500) - .getGrabbedOutOnlyString(); - s = d.trim(); + s = tput(str,500,session); if (s.isEmpty()) { return null; } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/config/DefaultNRepositoryModel.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/config/DefaultNRepositoryModel.java index 440fbabab..6de9055d6 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/config/DefaultNRepositoryModel.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/config/DefaultNRepositoryModel.java @@ -168,7 +168,7 @@ public void removeAllRepositories(NSession session) { protected void addRepository(NRepository repo, NSession session, boolean temp, boolean enabled) { repositoryRegistryHelper.addRepository(repo, session); - repo.setEnabled(enabled, session); + repo.config().setSession(session).setEnabled(enabled); NConfigs.of(session).save(); if (!temp) { NConfigsExt config = NConfigsExt.of(NConfigs.of(session)); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/AbstractNRepository.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/AbstractNRepository.java index 0adae8f69..fe57f3c5a 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/AbstractNRepository.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/AbstractNRepository.java @@ -10,7 +10,7 @@ * other 'things' . Its based on an extensible architecture to help supporting a * large range of sub managers / repositories. *
- * + *

* Copyright [2020] [thevpc] Licensed under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -35,6 +35,7 @@ import net.thevpc.nuts.spi.NRepositorySPI; import java.util.*; + import net.thevpc.nuts.runtime.standalone.workspace.config.NRepositoryConfigManagerExt; import net.thevpc.nuts.runtime.standalone.security.DefaultNRepositorySecurityManager; import net.thevpc.nuts.runtime.standalone.security.DefaultNRepositorySecurityModel; @@ -58,6 +59,7 @@ public abstract class AbstractNRepository implements NRepository, NRepositorySPI protected NSession initSession; protected NCachedValue available = new NCachedValue<>(this::isAvailableImpl, 0); protected boolean supportsDeploy; + protected boolean enabled=true; public AbstractNRepository() { userProperties = new DefaultObservableMap<>(); @@ -172,11 +174,11 @@ public List> getUserPropertyListeners() { } public boolean isEnabled(NSession session) { - return this.config().setSession(session).isEnabled(); + return this.enabled && this.config().setSession(session).isEnabled(); } public NRepository setEnabled(boolean enabled, NSession session) { - this.config().setSession(session).setEnabled(enabled); + this.enabled = enabled; return this; } @@ -217,7 +219,7 @@ public NPath getIdBasedir(NId id, NSession session) { } public String getIdFilename(NId id, NSession session) { - return getIdFilename(id,getIdExtension(id, session),session); + return getIdFilename(id, getIdExtension(id, session), session); } public String getIdFilename(NId id, String ext, NSession session) { diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/folder/NFolderRepositoryBase.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/folder/NFolderRepositoryBase.java index dcbd80438..65b09f18f 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/folder/NFolderRepositoryBase.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/folder/NFolderRepositoryBase.java @@ -34,6 +34,7 @@ public NFolderRepositoryBase(NAddRepositoryOptions options, speed == null ? (NPath.of(options.getConfig().getLocation().getPath() , session).isRemote() ? NSpeedQualifier.SLOW : NSpeedQualifier.FASTER) : speed , supportedMirroring, repositoryType,supportsDeploy); + NPath locationPath = config().setSession(initSession).getLocationPath(); if (!isRemote()) { if (options.getConfig().getStoreStrategy() != NStoreStrategy.STANDALONE) { cache.setWriteEnabled(false); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/main/DefaultNInstalledRepository.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/main/DefaultNInstalledRepository.java index 3a7e0e6c4..2c09f9192 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/main/DefaultNInstalledRepository.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/repository/impl/main/DefaultNInstalledRepository.java @@ -52,6 +52,7 @@ import net.thevpc.nuts.runtime.standalone.util.filters.NIdFilterToPredicate; import net.thevpc.nuts.runtime.standalone.util.iter.IteratorBuilder; import net.thevpc.nuts.runtime.standalone.workspace.DefaultNWorkspace; +import net.thevpc.nuts.runtime.standalone.workspace.NWorkspaceExt; import net.thevpc.nuts.runtime.standalone.workspace.NWorkspaceUtils; import net.thevpc.nuts.runtime.standalone.xtra.expr.StringTokenizerUtils; import net.thevpc.nuts.spi.*; @@ -217,6 +218,7 @@ public void install(NId id, NSession session, NId forId) { NWorkspaceUtils.of(session).checkReadOnly(); InstallInfoConfig ii = getInstallInfoConfig(id, null, session); try { + invalidateInstallationDigest(session); String repository = id.getRepository(); NRepository r = NRepositories.of(session).findRepository(repository).orNull(); if (ii == null) { @@ -543,6 +545,7 @@ public NInstallInformation getInstallInformation(InstallInfoConfig ii, NSession } private NInstallInformation updateInstallInformation(NDefinition def, Boolean install, Boolean require, boolean deploy, NSession session) { + invalidateInstallationDigest(session); NId id1 = def.getId(); InstallInfoConfig ii = getInstallInfoConfig(id1, null, session); boolean wasInstalled = false; @@ -693,6 +696,7 @@ public NDeployRepositoryCommand deploy() { return new AbstractNDeployRepositoryCommand(this) { @Override public NDeployRepositoryCommand run() { + invalidateInstallationDigest(getSession()); boolean succeeded = false; try { NDescriptor rep = deployments.deploy(this, NConfirmationMode.YES); @@ -712,6 +716,7 @@ public NRepositoryUndeployCommand undeploy() { return new AbstractNRepositoryUndeployCommand(this) { @Override public NRepositoryUndeployCommand run() { + invalidateInstallationDigest(getSession()); boolean succeeded = false; try { deployments.undeploy(this); @@ -724,6 +729,11 @@ public NRepositoryUndeployCommand run() { }; } + private static void invalidateInstallationDigest(NSession session) { + String uuid = UUID.randomUUID().toString(); + NWorkspaceExt.of(session).setInstallationDigest(uuid,session); + } + @Override public NPushRepositoryCommand push() { return new AbstractNPushRepositoryCommand(this) { @@ -831,6 +841,7 @@ public NUpdateRepositoryStatisticsCommand updateStatistics() { return new AbstractNUpdateRepositoryStatisticsCommand(this) { @Override public NUpdateRepositoryStatisticsCommand run() { + invalidateInstallationDigest(getSession()); deployments.reindexFolder(getSession()); return this; } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/session/NWorkspaceSessionAwareImpl.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/session/NWorkspaceSessionAwareImpl.java index f676ee7a0..980e4ac4b 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/session/NWorkspaceSessionAwareImpl.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/session/NWorkspaceSessionAwareImpl.java @@ -203,4 +203,14 @@ public NWorkspaceModel getModel() { public String toString() { return ws.toString(); } + + @Override + public String getInstallationDigest() { + return ((NWorkspaceExt) ws).getInstallationDigest(); + } + + @Override + public void setInstallationDigest(String value, NSession session) { + ((NWorkspaceExt) ws).setInstallationDigest(value, session); + } } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/text/DefaultNTexts.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/text/DefaultNTexts.java index 21889aeb9..a3a90564e 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/text/DefaultNTexts.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/text/DefaultNTexts.java @@ -6,6 +6,8 @@ import net.thevpc.nuts.elem.NElements; import net.thevpc.nuts.format.NFormat; import net.thevpc.nuts.format.NFormattable; +import net.thevpc.nuts.format.NMsgFormattable; +import net.thevpc.nuts.format.NStringFormattable; import net.thevpc.nuts.io.NIO; import net.thevpc.nuts.io.NPrintStream; import net.thevpc.nuts.log.NLogOp; @@ -59,6 +61,8 @@ public DefaultNTexts(NSession session) { private void registerDefaults() { register(NFormattable.class, (o, t, s) -> (((NFormattable) o).formatter(session).setSession(getSession()).setNtf(true).format()).toText()); + register(NStringFormattable.class, (o, t, s) -> (((NStringFormattable) o).format(session)).toText()); + register(NMsgFormattable.class, (o, t, s) -> _NMsg_toString((((NMsgFormattable) o).toMsg()))); register(NMsg.class, (o, t, s) -> _NMsg_toString((NMsg) o)); register(NString.class, (o, t, s) -> ((NString) o).toText()); register(InputStream.class, (o, t, s) -> t.ofStyled(NIO.of(s).ofInputSource((InputStream) o).getMetaData().getName().orElse(o.toString()), NTextStyle.path())); @@ -1420,10 +1424,9 @@ public NText toText(Number object, NSession session) { } case "memory": case "bytes": - case "size": - { + case "size": { String p = NStringUtils.trim(pattern); - BytesSizeFormat d = new BytesSizeFormat(null,session); + BytesSizeFormat d = new BytesSizeFormat(null, session); if (Number.class.isAssignableFrom(expectedType)) { return NOptional.of( (NTextFormat) new NTextFormat() { diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/util/DefaultSourceControlHelper.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/util/DefaultSourceControlHelper.java index 4ab5911a0..3b8da63fa 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/util/DefaultSourceControlHelper.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/util/DefaultSourceControlHelper.java @@ -114,7 +114,7 @@ public NDefinition checkout(NId id, Path folder, NSession session) { nutToInstall.getRepositoryName(), newId.getLongId(), d, NPath.of(folder, session).setUserCache(false).setUserTemporary(false), - null, null, session + null, null, null,session ); } else { throw new NUnsupportedOperationException(session, NMsg.ofPlain("checkout not supported")); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/web/NWebCliImpl.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/web/NWebCliImpl.java index fa01f06d7..70a8af38c 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/web/NWebCliImpl.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/web/NWebCliImpl.java @@ -14,6 +14,7 @@ import net.thevpc.nuts.web.*; import java.io.IOException; +import java.io.UncheckedIOException; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; @@ -174,9 +175,10 @@ public NWebResponse run(NWebRequest r) { NAssert.requireNonNull(r, "request"); NAssert.requireNonNull(r.getMethod(), "method"); NHttpMethod method = r.getMethod(); - + String spec=null; try { - URL h = new URL(formatURL(r,false)); + spec = formatURL(r, false); + URL h = new URL(spec); HttpURLConnection uc = null; try { uc = (HttpURLConnection) h.openConnection(); @@ -258,8 +260,8 @@ public NWebResponse run(NWebRequest r) { } } } - } catch (IOException e) { - throw new RuntimeException(e); + } catch (IOException ex) { + throw new UncheckedIOException("error loading "+spec,ex); } } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspace.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspace.java index 3fbe06086..88673e30d 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspace.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspace.java @@ -38,6 +38,7 @@ import net.thevpc.nuts.log.NLog; import net.thevpc.nuts.log.NLogOp; import net.thevpc.nuts.log.NLogVerb; +import net.thevpc.nuts.runtime.standalone.NLocationKey; import net.thevpc.nuts.runtime.standalone.log.DefaultNLog; import net.thevpc.nuts.text.*; import net.thevpc.nuts.util.DefaultNProperties; @@ -197,7 +198,7 @@ private void initWorkspace(NBootOptions bOption0) { NBootManager _boot = NBootManager.of(defaultSession()); NBootConfig cfg = new NBootConfig(); cfg.setWorkspace(workspaceLocation); - cfg.setApiVersion( this.wsModel.askedApiVersion); + cfg.setApiVersion(this.wsModel.askedApiVersion); cfg.setRuntimeId(this.wsModel.askedRuntimeId); cfg.setRuntimeBootDescriptor(bootOptions.getRuntimeBootDescriptor().orNull()); cfg.setExtensionBootDescriptors(bootOptions.getExtensionBootDescriptors().orNull()); @@ -338,10 +339,10 @@ private void initWorkspace(NBootOptions bOption0) { LOGCRF.log(NMsg.ofJ(" nuts-inherited-nuts-boot-args : {0}", System.getProperty("nuts.boot.args") == null ? NTextUtils.desc(null, text) : NTextUtils.desc(NCmdLine.of(System.getProperty("nuts.boot.args"), NShellFamily.SH, defaultSession()), text) )); - LOGCRF.log(NMsg.ofJ(" nuts-inherited-nuts-args : {0}", System.getProperty("nuts.args") == null ? NTextUtils.desc(null, text) + LOGCRF.log(NMsg.ofJ(" nuts-inherited-nuts-args : {0}", System.getProperty("nuts.args") == null ? NTextUtils.desc(null, text) : NTextUtils.desc(text.ofText(NCmdLine.of(System.getProperty("nuts.args"), NShellFamily.SH, defaultSession())), text) )); - LOGCRF.log(NMsg.ofJ(" nuts-open-mode : {0}", NTextUtils.formatLogValue(text, bootOptions.getOpenMode().orNull(), bootOptions.getOpenMode().orElse(NOpenMode.OPEN_OR_CREATE)))); + LOGCRF.log(NMsg.ofJ(" nuts-open-mode : {0}", NTextUtils.formatLogValue(text, bootOptions.getOpenMode().orNull(), bootOptions.getOpenMode().orElse(NOpenMode.OPEN_OR_CREATE)))); NEnvs senvs = NEnvs.of(defaultSession()); LOGCRF.log(NMsg.ofJ(" java-home : {0}", System.getProperty("java.home"))); LOGCRF.log(NMsg.ofJ(" java-classpath : {0}", System.getProperty("java.class.path"))); @@ -1904,6 +1905,21 @@ public DefaultImportModel getImportModel() { return wsModel.importModel; } + + @Override + public String getInstallationDigest() { + return wsModel.installationDigest; + } + + @Override + public void setInstallationDigest(String value,NSession session) { + this.wsModel.installationDigest = value; + this.wsModel.confDB.storeStringNonBlank(NLocationKey.of(NStoreType.CONF, getApiId(),"installation-digest"),value,session); + } + + + + public enum InstallStrategy0 implements NEnum { INSTALL, UPDATE, @@ -1918,12 +1934,10 @@ public static NOptional parse(String value) { return NEnumUtils.parseEnum(value, InstallStrategy0.class); } - @Override public String id() { return id; } - } } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspaceFactory.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspaceFactory.java index 9e2cddc7a..1eec10363 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspaceFactory.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/DefaultNWorkspaceFactory.java @@ -281,6 +281,7 @@ protected T newInstance(Class t, Class[] argTypes, Object[] args, Class a .log(NMsg.ofJ("unable to instantiate {0}", t)); } } + throw new NFactoryException(session, NMsg.ofC("instantiate '%s' failed", t), new NoSuchElementException("No constructor was found for "+t.getName())); } try { t1 = ctrl0.newInstance(args, session); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceExt.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceExt.java index 5395f83fc..8692fc145 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceExt.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceExt.java @@ -44,6 +44,7 @@ static NWorkspaceExt of(NWorkspace ws) { void installImpl(NDefinition def, String[] args, boolean updateDefaultVersion, NSession session); void updateImpl(NDefinition def, String[] args, boolean updateDefaultVersion, NSession session); + void uninstallImpl(NDefinition def, String[] args, boolean runInstaller, boolean deleteFiles, boolean eraseFiles, boolean traceBeforeEvent, NSession session); /** @@ -74,4 +75,8 @@ static NWorkspaceExt of(NWorkspace ws) { NSession defaultSession(); NWorkspaceModel getModel(); + + String getInstallationDigest(); + + void setInstallationDigest(String value,NSession session); } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceHelper.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceHelper.java index cb510ef59..de63f8dab 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceHelper.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/NWorkspaceHelper.java @@ -48,7 +48,7 @@ public static List _getEnabledRepositories(NRepository parent, NRep List subrepos = new ArrayList<>(); boolean ok = false; for (NRepository repository : parent.config().setSession(session).getMirrors()) { - if (repository.config().isEnabled()) { + if (repository.isEnabled(session)) { if (repositoryFilter == null || repositoryFilter.acceptRepository(repository)) { repos.add(repository); ok = true; diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/archetype/DefaultNWorkspaceArchetypeComponent.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/archetype/DefaultNWorkspaceArchetypeComponent.java index 3a70b3174..2bfb3633c 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/archetype/DefaultNWorkspaceArchetypeComponent.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/archetype/DefaultNWorkspaceArchetypeComponent.java @@ -48,15 +48,15 @@ public String getName() { @Override public void initializeWorkspace(NSession session) { - this.LOG = NLog.of(DefaultNWorkspaceArchetypeComponent.class,session); + this.LOG = NLog.of(DefaultNWorkspaceArchetypeComponent.class, session); DefaultNConfigs rm = (DefaultNConfigs) NConfigs.of(session); LinkedHashMap def = new LinkedHashMap<>(); List defaults = new ArrayList<>(); for (NAddRepositoryOptions d : rm.getDefaultRepositories()) { if (d.getConfig() != null) { - def.put(NPath.of(d.getConfig().getLocation().getPath(),session).toAbsolute().toString(), d); + def.put(NPath.of(d.getConfig().getLocation().getPath(), session).toAbsolute().toString(), d); } else { - def.put(NPath.of(d.getLocation(),session).toAbsolute().toString(), d); + def.put(NPath.of(d.getLocation(), session).toAbsolute().toString(), d); } defaults.add(NRepositoryLocation.of(d.getName(), null)); } @@ -64,13 +64,24 @@ public void initializeWorkspace(NSession session) { NRepositoryLocation[] br = rm.getModel().resolveBootRepositoriesList(session).resolve(defaults.toArray(new NRepositoryLocation[0]), NRepositoryDB.of(session)); for (NRepositoryLocation s : br) { NAddRepositoryOptions oo = NRepositorySelectorHelper.createRepositoryOptions(s, false, session); - String sloc = NPath.of(oo.getConfig().getLocation().getPath(),session).toAbsolute().toString(); + String sloc = NPath.of(oo.getConfig().getLocation().getPath(), session).toAbsolute().toString(); if (def.containsKey(sloc)) { NAddRepositoryOptions r = def.get(sloc).copy(); - if(!NBlankable.isBlank(s.getName())){ + if (!NBlankable.isBlank(s.getName())) { r.setName(oo.getName()); } - NRepositories.of(session).addRepository(r); + NRepository nr = NRepositories.of(session).addRepository(r); + if ( + "system".equals(nr.getName()) + && "system".equals(nr.config().getGlobalName()) + && ( + nr.config().getLocationPath() == null + || !nr.config().getLocationPath().isDirectory() + ) + ) { + //runtime disable system repo if it is not accessible. + nr.setEnabled(false, session); + } def.remove(sloc); } else { NRepositories.of(session).addRepository(oo diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/DefaultNQueryBaseOptions.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/DefaultNQueryBaseOptions.java index 7c15b9c29..66d9f75b3 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/DefaultNQueryBaseOptions.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/DefaultNQueryBaseOptions.java @@ -13,8 +13,6 @@ import net.thevpc.nuts.util.NBlankable; import net.thevpc.nuts.util.NLiteral; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; import java.util.EnumSet; @@ -35,7 +33,6 @@ public abstract class DefaultNQueryBaseOptions exte private boolean inlineDependencies = false; private boolean dependencies = false; private boolean effective = false; - private Path location = null; private NFetchDisplayOptions displayOptions; private NRepositoryFilter repositoryFilter; @@ -55,18 +52,11 @@ public T copyFromDefaultNQueryBaseOptions(DefaultNQueryBaseOptions other) { super.copyFromWorkspaceCommandBase(other); this.optional = other.getOptional(); this.failFast = other.isFailFast(); -// this.fetchStrategy = other.getFetchStrategy(); -// this.indexed = other.getIndexed(); -// this.transitive = other.isTransitive(); -// this.cached = other.isCached(); this.content = other.isContent(); this.inlineDependencies = other.isInlineDependencies(); this.dependencies = other.isDependencies(); this.effective = other.isEffective(); this.scope = EnumSet.copyOf(other.getScope()); - this.location = other.getLocation(); -// this.repos.clear(); -// this.repos.addAll(Arrays.asList(other.getRepositories())); this.dependencyFilter = other.getDependencyFilter(); this.repositoryFilter = other.getRepositoryFilter(); @@ -215,24 +205,6 @@ public T dependencies() { return setDependencies(true); } - - //@Override - public Path getLocation() { - return location; - } - - //@Override - public T setLocation(Path location) { - this.location = location; - return (T) this; - } - - //@Override - public T setDefaultLocation() { - this.location = null; - return (T) this; - } - public boolean isFailFast() { return failFast; } @@ -331,10 +303,6 @@ public boolean configureFirst(NCmdLine cmdLine) { cmdLine.withNextFlag((v, r, s) -> this.setContent(v)); return true; } - case "--location": { - cmdLine.withNextEntry((v, r, s) -> this.setLocation(NBlankable.isBlank(v) ? null : Paths.get(v))); - return true; - } } return false; } @@ -384,7 +352,6 @@ public String toString() { + ", inlineDependencies=" + inlineDependencies + ", dependencies=" + dependencies + ", effective=" + effective - + ", location=" + location // + ", repos=" + repos + ", displayOptions=" + displayOptions + ", session=" + getSession() diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/deploy/DefaultNDeployCommand.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/deploy/DefaultNDeployCommand.java index 8537c2494..1b5428e2d 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/deploy/DefaultNDeployCommand.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/deploy/DefaultNDeployCommand.java @@ -244,7 +244,7 @@ private NDeployCommand runDeployFile(NInputSource content, Object descriptor0, S } } else { NRepository repo = NRepositories.of(getSession()).findRepository(repository).get(); - if (!repo.config().isEnabled()) { + if (!repo.isEnabled(session)) { throw new NRepositoryDisabledException(getSession(), repository); } effId = CoreNIdUtils.createContentFaceId(effId.builder().setPropertiesQuery("").build(), descriptor, session); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/exec/DefaultNExecCommand.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/exec/DefaultNExecCommand.java index 574c8860c..a7bdf2890 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/exec/DefaultNExecCommand.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/exec/DefaultNExecCommand.java @@ -78,7 +78,7 @@ public DefaultNExecCommand(NSession session) { private void refactorCommand() { - if(getCommandDefinition()!=null){ + if (getCommandDefinition() != null) { return; } boolean someUpdates = true; @@ -135,7 +135,7 @@ public NExecutableInformation which() { NAssert.requireNonBlank(command, "command", session); String target = getTarget(); if (!NBlankable.isBlank(target)) { - throw new NIllegalArgumentException(session, NMsg.ofC("cannot run %s command remotely",executionType)); + throw new NIllegalArgumentException(session, NMsg.ofC("cannot run %s command remotely", executionType)); } String[] ts = command.toArray(new String[0]); exec = new DefaultNOpenExecutable(ts, getExecutorOptions().toArray(new String[0]), this); @@ -143,7 +143,7 @@ public NExecutableInformation which() { } case SYSTEM: { RemoteInfo0 remoteInfo0 = resolveRemoteInfo0(); - if (remoteInfo0!=null) { + if (remoteInfo0 != null) { NExecutionType finalExecutionType = executionType; NAssert.requireNull(getCommandDefinition(), () -> NMsg.ofC("unable to run artifact as %s cmd", finalExecutionType), session); NAssert.requireNonBlank(command, "command", session); @@ -156,7 +156,7 @@ public NExecutableInformation which() { remoteInfo0.out0, remoteInfo0.err0 ); - }else { + } else { NExecutionType finalExecutionType = executionType; NAssert.requireNull(getCommandDefinition(), () -> NMsg.ofC("unable to run artifact as %s cmd", finalExecutionType), session); NAssert.requireNonBlank(command, "command", session); @@ -179,10 +179,10 @@ public NExecutableInformation which() { case EMBEDDED: { if (getCommandDefinition() != null) { RemoteInfo0 remoteInfo0 = resolveRemoteInfo0(); - if (remoteInfo0!=null) { + if (remoteInfo0 != null) { String[] ts = command == null ? new String[0] : command.toArray(new String[0]); return new DefaultSpawnExecutableNutsRemote(remoteInfo0.commExec, getCommandDefinition(), ts, getExecutorOptions(), this, remoteInfo0.in0, remoteInfo0.out0, remoteInfo0.err0); - }else { + } else { String[] ts = command == null ? new String[0] : command.toArray(new String[0]); return ws_execDef(getCommandDefinition(), getCommandDefinition().getId().getLongName(), ts, getExecutorOptions(), workspaceOptions, env, directory, failFast, executionType, runAs); @@ -367,7 +367,7 @@ private NExecutableInformationExt execEmbeddedOrExternal(String[] cmd, List ts = new ArrayList<>(command); NDefinition def2 = NSearchCommand.of(getSession()) @@ -381,7 +381,7 @@ private NExecutableInformationExt execEmbeddedOrExternal(String[] cmd, List 0) , DefaultNInstallInfo.notInstalled(_id), - null, session + null, null, session ); NDependencySolver resolver = NDependencySolver.of(session); NDependencyFilters ff = NDependencyFilters.of(session); @@ -449,7 +449,7 @@ private NExecutableInformationExt execEmbeddedOrExternal(String[] cmd, List ts = new ArrayList<>(command); if (ts.size() == 0) { @@ -469,7 +469,7 @@ private NExecutableInformationExt execEmbeddedOrExternal(String[] cmd, List NMsg.ofC("unable to run artifact as %s cmd", finalExecutionType), session); NAssert.requireNonBlank(command, "command", session); @@ -1027,7 +1027,7 @@ private RemoteInfo0 resolveRemoteInfo0() { NExtensions.of(session) .loadExtension(NId.of("com.cts.nuts.enterprise:next-agent").get()); } - RemoteInfo0 ii=new RemoteInfo0(); + RemoteInfo0 ii = new RemoteInfo0(); ii.commExec = NExtensions.of(session).createComponent(NExecCommandExtension.class, connexionString) .orElseThrow(() -> new NIllegalArgumentException(session, NMsg.ofC("invalid execution target string : %s", target))); ii.in0 = CoreIOUtils.validateIn(in, session); @@ -1037,7 +1037,8 @@ private RemoteInfo0 resolveRemoteInfo0() { } return null; } - private static class RemoteInfo0{ + + private static class RemoteInfo0 { NExecCommandExtension commExec; NExecInput in0; NExecOutput out0; diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/AbstractNFetchCommand.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/AbstractNFetchCommand.java index 01a62279e..a2f503079 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/AbstractNFetchCommand.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/AbstractNFetchCommand.java @@ -110,7 +110,6 @@ public String toString() { + ", inlineDependencies=" + isInlineDependencies() + ", dependencies=" + isDependencies() + ", effective=" + isEffective() - + ", location=" + getLocation() + ", repos=" + getRepositoryFilter() + ", displayOptions=" + getDisplayOptions() + ", id=" + getId() diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/DefaultNFetchCommand.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/DefaultNFetchCommand.java index da339eefb..f46f805f1 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/DefaultNFetchCommand.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/fetch/DefaultNFetchCommand.java @@ -2,6 +2,11 @@ import net.thevpc.nuts.*; import net.thevpc.nuts.elem.NElements; +import net.thevpc.nuts.runtime.standalone.NLocationKey; +import net.thevpc.nuts.runtime.standalone.definition.DefaultNDefinitionRef; +import net.thevpc.nuts.runtime.standalone.io.cache.CachedSupplier; +import net.thevpc.nuts.runtime.standalone.io.cache.DefaultCachedSupplier; +import net.thevpc.nuts.runtime.standalone.util.collections.LRUMap; import net.thevpc.nuts.security.NDigest; import net.thevpc.nuts.io.NPath; import net.thevpc.nuts.runtime.standalone.dependency.util.NDependencyUtils; @@ -13,7 +18,6 @@ import net.thevpc.nuts.runtime.standalone.repository.cmd.NRepositorySupportedAction; import net.thevpc.nuts.runtime.standalone.definition.DefaultNDefinition; import net.thevpc.nuts.runtime.standalone.repository.impl.main.NInstalledRepository; -import net.thevpc.nuts.runtime.standalone.io.util.CoreIOUtils; import net.thevpc.nuts.runtime.standalone.definition.DefaultNInstallInfo; import net.thevpc.nuts.runtime.standalone.repository.impl.main.DefaultNInstalledRepository; import net.thevpc.nuts.runtime.standalone.dependency.NDependencyScopes; @@ -27,9 +31,10 @@ import net.thevpc.nuts.util.NBlankable; import net.thevpc.nuts.util.NMsg; -import java.nio.file.Files; import java.nio.file.Path; import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.logging.Level; public class DefaultNFetchCommand extends AbstractNFetchCommand { @@ -139,14 +144,10 @@ public NInstallInformation getResultInstallInformation() { } } - public Path getResultPath() { + public NPath getResultPath() { try { NDefinition def = fetchDefinition(getId(), copy().setContent(true).setEffective(false), true, false); - Path p = def.getContent().flatMap(NPath::toPath).orNull(); - if (getLocation() != null) { - return getLocation(); - } - return p; + return def.getContent().orNull(); } catch (NNotFoundException ex) { if (!isFailFast()) { return null; @@ -170,178 +171,86 @@ public NFetchCommand run() { } public NDefinition fetchDefinition(NId id, NFetchCommand options, boolean includeContent, boolean includeInstallInfo) { - NDefinition d = fetchDefinitionNoCache(id, options, includeContent, includeInstallInfo); - return d; - } - - public NDefinition fetchDefinitionNoCache(NId id, NFetchCommand options, boolean includeContent, boolean includeInstallInfo) { - long startTime = System.currentTimeMillis(); - checkSession(); - NWorkspaceUtils wu = NWorkspaceUtils.of(session); - CoreNIdUtils.checkLongId(id, session); + LRUMap> cachedDefs = NWorkspaceExt.of(ws).getModel().cachedDefs; + NId longId = id.getLongId(); + Function> supp = id0 -> { + Supplier supplier = new Supplier() { + @Override + public NDefinition get() { + long startTime = System.currentTimeMillis(); + checkSession(); + NWorkspaceUtils wu = NWorkspaceUtils.of(session); + CoreNIdUtils.checkLongId(id, session); // checkSession(); - NSession _ws = getSession(); - NSessionUtils.checkSession(this.ws, options.getSession()); - NWorkspaceExt dws = NWorkspaceExt.of(_ws); - NFetchStrategy nutsFetchModes = NWorkspaceHelper.validate(_ws.getFetchStrategy()); - NRepositoryFilter repositoryFilter = this.getRepositoryFilter(); - if (!NBlankable.isBlank(id.getRepository())) { - NRepositoryFilter repositoryFilter2 = NRepositoryFilters.of(_ws).byName(id.getRepository()); - repositoryFilter = repositoryFilter2.and(repositoryFilter); - } - NRepositoryAndFetchModeTracker descTracker = new NRepositoryAndFetchModeTracker( - wu.filterRepositoryAndFetchModes(NRepositorySupportedAction.SEARCH, id, repositoryFilter, - nutsFetchModes, session) - ); - - DefaultNDefinition foundDefinition = null; - List reasons = new ArrayList<>(); - NRepositoryAndFetchMode successfulDescriptorLocation = null; - NRepositoryAndFetchMode successfulContentLocation = null; - try { - //add env parameters to fetch adequate nuts - id = wu.configureFetchEnv(id); - DefaultNDefinition result = null; - for (NRepositoryAndFetchMode location : descTracker.available()) { - try { - result = fetchDescriptorAsDefinition(id, session, nutsFetchModes, location.getFetchMode(), location.getRepository()); - successfulDescriptorLocation = location; - break; - } catch (NNotFoundException exc) { - // - descTracker.addFailure(location); - } catch (Exception ex) { - //ignore - _LOGOP(getSession()).error(ex).level(Level.SEVERE) - .log(NMsg.ofJ("unexpected error while fetching descriptor for {0}", id)); - if (_LOG(getSession()).isLoggable(Level.FINEST)) { - NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, id.getLongId(), NLogVerb.FAIL, "fetch def", startTime); + NSession _ws = getSession(); + NSessionUtils.checkSession(ws, options.getSession()); + NWorkspaceExt dws = NWorkspaceExt.of(_ws); + NFetchStrategy nutsFetchModes = NWorkspaceHelper.validate(_ws.getFetchStrategy()); + NRepositoryFilter repositoryFilter = getRepositoryFilter(); + if (!NBlankable.isBlank(id.getRepository())) { + NRepositoryFilter repositoryFilter2 = NRepositoryFilters.of(_ws).byName(id.getRepository()); + repositoryFilter = repositoryFilter2.and(repositoryFilter); } - descTracker.addFailure(location); - } - } - foundDefinition = result; - if (foundDefinition != null) { - if (options.isEffective() || isDependencies()) { + NRepositoryAndFetchModeTracker descTracker = new NRepositoryAndFetchModeTracker( + wu.filterRepositoryAndFetchModes(NRepositorySupportedAction.SEARCH, id, repositoryFilter, + nutsFetchModes, session) + ); + List reasons = new ArrayList<>(); try { - foundDefinition.setEffectiveDescriptor(dws.resolveEffectiveDescriptor(foundDefinition.getDescriptor(), session)); - } catch (NNotFoundException ex) { - //ignore - _LOGOP(getSession()).level(Level.WARNING).verb(NLogVerb.WARNING) - .log(NMsg.ofJ("artifact descriptor found, but one of its parents or dependencies is not: {0} : missing {1}", id, - ex.getId())); - foundDefinition = null; - } - } - if (foundDefinition != null) { - if (isDependencies()) { - foundDefinition.setDependencies( - NDependencySolver.of(getSession()) - .setFilter(buildActualDependencyFilter()) - .add(id.toDependency(), foundDefinition) - .solve() - ); - } - //boolean includeContent = shouldIncludeContent(options); - // always ok for content, if 'content' flag is not armed, try find 'local' path - NInstalledRepository installedRepository = dws.getInstalledRepository(); - if (includeContent) { - if (!NDescriptorUtils.isNoContent(foundDefinition.getDescriptor())) { - boolean loadedFromInstallRepo = DefaultNInstalledRepository.INSTALLED_REPO_UUID.equals(successfulDescriptorLocation - .getRepository().getUuid()); - NId id1 = CoreNIdUtils.createContentFaceId(foundDefinition.getId(), foundDefinition.getDescriptor(), session); - Path copyTo = options.getLocation(); - if (copyTo != null && Files.isDirectory(copyTo)) { - copyTo = copyTo.resolve(NLocations.of(_ws).getDefaultIdFilename(id1)); - } -// boolean escalateMode = false; - boolean contentSuccessful = false; - NRepositoryAndFetchModeTracker contentTracker = new NRepositoryAndFetchModeTracker(descTracker.available()); - - contentSuccessful = fetchContent(id1, foundDefinition, successfulDescriptorLocation, copyTo, reasons); - if (contentSuccessful) { - successfulContentLocation = successfulDescriptorLocation; - } else { - contentTracker.addFailure(successfulDescriptorLocation); - } - if (!contentSuccessful && !loadedFromInstallRepo) { - if (successfulDescriptorLocation.getFetchMode() == NFetchMode.LOCAL) { - NRepositoryAndFetchMode finalSuccessfulDescriptorLocation = successfulDescriptorLocation; - NRepositoryAndFetchMode n = contentTracker.available().stream() - .filter(x -> x.getRepository().getUuid().equals(finalSuccessfulDescriptorLocation.getRepository().getUuid()) && - x.getFetchMode() == NFetchMode.REMOTE).findFirst().orElse(null); - if (n != null/* && contentTracker.accept(n)*/) { - contentSuccessful = fetchContent(id1, foundDefinition, n, copyTo, reasons); - if (contentSuccessful) { - successfulContentLocation = n; - } else { - contentTracker.addFailure(n); - } - } + //add env parameters to fetch adequate nuts + NId id2 = wu.configureFetchEnv(id); + NDefinition result = null; + for (NRepositoryAndFetchMode fetchLocation : descTracker.available()) { + try { + result = fetchDescriptorAsDefinition(id2, session, nutsFetchModes, fetchLocation, descTracker); + if (result != null) { + return result; } - } - if (!contentSuccessful) { - for (NRepositoryAndFetchMode repoAndMode : contentTracker.available()) { - contentSuccessful = fetchContent(id1, foundDefinition, repoAndMode, copyTo, reasons); - if (contentSuccessful) { - successfulContentLocation = repoAndMode; - break; - } else { - contentTracker.addFailure(repoAndMode); - } + break; + } catch (NNotFoundException exc) { + // + descTracker.addFailure(fetchLocation); + } catch (Exception ex) { + //ignore + _LOGOP(getSession()).error(ex).level(Level.SEVERE) + .log(NMsg.ofJ("unexpected error while fetching descriptor for {0}", id2)); + if (_LOG(getSession()).isLoggable(Level.FINEST)) { + NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, id2.getLongId(), NLogVerb.FAIL, "fetch def", startTime); } + descTracker.addFailure(fetchLocation); } - if (contentSuccessful) { - if (loadedFromInstallRepo && successfulContentLocation != successfulDescriptorLocation) { - //this happens if the jar content is no more installed while its descriptor is still installed. - NRepositorySPI installedRepositorySPI = wu.repoSPI(installedRepository); - installedRepositorySPI.deploy() - .setId(foundDefinition.getId()) - .setDescriptor(foundDefinition.getDescriptor()) - .setSession(this.session.copy().setConfirm(NConfirmationMode.YES)) - //.setFetchMode(mode) - .setContent(foundDefinition.getContent().get(session)) - .run(); - - } - } - if (!contentSuccessful /*&& includedRemote*/) { - NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, id.getLongId(), NLogVerb.FAIL, - "fetched descriptor but failed to fetch artifact binaries", startTime); - } - } - } - if (includeInstallInfo) { - //will always load install information - NInstallInformation ii = installedRepository.getInstallInformation(id, this.session); - if (ii != null) { -// ((DefaultNInstalledRepository) (dws.getInstalledRepository())).updateInstallInfoConfigInstallDate(id, Instant.now(), session); - foundDefinition.setInstallInformation(ii); - } else { - foundDefinition.setInstallInformation(DefaultNInstallInfo.notInstalled(id)); } + + } catch (NNotFoundException ex) { + reasons.add(ex); + NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, longId, NLogVerb.FAIL, "fetch definition", startTime); + throw ex; + } catch (RuntimeException ex) { + NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, longId, NLogVerb.FAIL, "[unexpected] fetch definition", startTime); + throw ex; } + throw new NNotFoundException(getSession(), id); } + }; + DefaultCachedSupplier.SimpleCacheValidator validator = new DefaultCachedSupplier.SimpleCacheValidator(session); + return DefaultCachedSupplier.of( + CachedSupplier.NCacheLevel.MEM, + NDefinition.class, + NLocationKey.ofCache(id, "def", null), supplier, validator, + session + ); + }; + if (cachedDefs.containsKey(longId)) { + CachedSupplier u = cachedDefs.get(longId); + if (u == null) { + throw new IllegalArgumentException("circular loading of " + longId); } - } catch (NNotFoundException ex) { - reasons.add(ex); - NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, id.getLongId(), NLogVerb.FAIL, "fetch definition", startTime); - throw ex; - } catch (RuntimeException ex) { - NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, id.getLongId(), NLogVerb.FAIL, "[unexpected] fetch definition", startTime); - throw ex; + return u.getValue(); } - if (foundDefinition != null) { -// if (getSession().isTrace()) { -// NutsIterableOutput ff = CoreNutsUtils.getValidOutputFormat(getSession()) -// .session(getSession()); -// ff.start(); -// ff.next(foundDefinition); -// ff.complete(); -// } - return foundDefinition; - } - throw new NNotFoundException(getSession(), id); + cachedDefs.put(longId, null); + CachedSupplier uu = supp.apply(longId); + cachedDefs.put(longId, uu); + return uu.getValue(); } private NDependencyFilter buildActualDependencyFilter() { @@ -381,26 +290,6 @@ protected boolean fetchContent(NId id1, DefaultNDefinition foundDefinition, NRep return false; } - protected boolean fetchContent(NId id1, DefaultNDefinition foundDefinition, NRepositoryAndFetchMode repo, Path copyTo, List reasons) { - NRepositorySPI repoSPI = NWorkspaceUtils.of(getSession()).repoSPI(repo.getRepository()); - try { - NPath content = repoSPI.fetchContent() - .setId(id1).setDescriptor(foundDefinition.getDescriptor()) - .setLocalPath(copyTo == null ? null : copyTo.toString()) - .setSession(session) - .setFetchMode(repo.getFetchMode()) - .getResult(); - if (content != null) { - foundDefinition.setContent(content); - foundDefinition.setDescriptor(resolveExecProperties(foundDefinition.getDescriptor(), content)); - return true; - } - } catch (NNotFoundException ex) { - reasons.add(ex); - // - } - return false; - } protected NDescriptor resolveExecProperties(NDescriptor nutsDescriptor, NPath jar) { checkSession(); @@ -462,116 +351,130 @@ protected NDescriptor resolveExecProperties(NDescriptor nutsDescriptor, NPath ja return nb.build(); } - protected DefaultNDefinition fetchDescriptorAsDefinition(NId id, NSession session, NFetchStrategy nutsFetchModes, NFetchMode mode, NRepository repo) { + protected NDefinition fetchDescriptorAsDefinition(NId id, NSession session, NFetchStrategy nutsFetchModes, NRepositoryAndFetchMode location, NRepositoryAndFetchModeTracker descTracker) { + NFetchMode mode = location.getFetchMode(); + NRepository repo = location.getRepository(); checkSession(); NSessionUtils.checkSession(this.ws, session); NWorkspaceExt dws = NWorkspaceExt.of(session); boolean withCache = !(repo instanceof DefaultNInstalledRepository) && session.isCached(); - NPath cachePath = null; - NWorkspaceUtils wu = NWorkspaceUtils.of(session); - NElements elem = NElements.of(session); - if (withCache) { - cachePath = NLocations.of(session).getStoreLocation(id, NStoreType.CACHE, repo.getUuid()) - .resolve(NLocations.of(session).getDefaultIdFilename(id.builder().setFace("def.cache").build())); - if (cachePath.isRegularFile()) { - try { - if (CoreIOUtils.isObsoletePath(session, cachePath)) { - //this is invalid cache! - cachePath.delete(); - } else { - DefaultNDefinition d = elem.setSession(session) - .json().parse(cachePath, DefaultNDefinition.class); - if (d != null) { - NRepositories rr = NRepositories.of(session.copy().setTransitive(true)); - NRepository repositoryById = rr.findRepositoryById(d.getRepositoryUuid()).orNull(); - NRepository repositoryByName = rr.findRepositoryByName(d.getRepositoryName()).orNull(); - if (repositoryById == null || repositoryByName == null) { - //this is invalid cache! - cachePath.delete(); - } else { - NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, id.getLongId(), NLogVerb.CACHE, "fetch definition", 0); - return d; - } - } - } - } catch (Exception ex) { - // + Supplier supplier = () -> { + NWorkspaceUtils wu = NWorkspaceUtils.of(session); + NRepositorySPI repoSPI = wu.repoSPI(repo); + NDescriptor descriptor = repoSPI.fetchDescriptor().setId(id) + .setSession(session).setFetchMode(mode) + .getResult(); + if (descriptor != null) { + NId nutsId = dws.resolveEffectiveId(descriptor, session); + NIdBuilder newIdBuilder = nutsId.builder(); + if (NBlankable.isBlank(newIdBuilder.getRepository())) { + newIdBuilder.setRepository(repo.getName()); } - } - } - - NRepositorySPI repoSPI = wu.repoSPI(repo); - NDescriptor descriptor = repoSPI.fetchDescriptor().setId(id) - .setSession(session).setFetchMode(mode) - .getResult(); - if (descriptor != null) { - NId nutsId = dws.resolveEffectiveId(descriptor, session); - NIdBuilder newIdBuilder = nutsId.builder(); - if (NBlankable.isBlank(newIdBuilder.getRepository())) { - newIdBuilder.setRepository(repo.getName()); - } - //inherit classifier from requested parse - String classifier = id.getClassifier(); - if (!NBlankable.isBlank(classifier)) { - newIdBuilder.setClassifier(classifier); - } - Map q = id.getProperties(); - if (!NDependencyScopes.isDefaultScope(q.get(NConstants.IdProperties.SCOPE))) { - newIdBuilder.setProperty(NConstants.IdProperties.SCOPE, q.get(NConstants.IdProperties.SCOPE)); - } - if (!NDependencyUtils.isDefaultOptional(q.get(NConstants.IdProperties.OPTIONAL))) { - newIdBuilder.setProperty(NConstants.IdProperties.OPTIONAL, q.get(NConstants.IdProperties.OPTIONAL)); - } - NId newId = newIdBuilder.build(); + //inherit classifier from requested parse + String classifier = id.getClassifier(); + if (!NBlankable.isBlank(classifier)) { + newIdBuilder.setClassifier(classifier); + } + Map q = id.getProperties(); + if (!NDependencyScopes.isDefaultScope(q.get(NConstants.IdProperties.SCOPE))) { + newIdBuilder.setProperty(NConstants.IdProperties.SCOPE, q.get(NConstants.IdProperties.SCOPE)); + } + if (!NDependencyUtils.isDefaultOptional(q.get(NConstants.IdProperties.OPTIONAL))) { + newIdBuilder.setProperty(NConstants.IdProperties.OPTIONAL, q.get(NConstants.IdProperties.OPTIONAL)); + } + NId newId = newIdBuilder.build(); - NId apiId0 = null; - NId apiId = null; + NId apiId0 = null; + NId apiId = null; - if (getId().getShortName().equals(NConstants.Ids.NUTS_API)) { - // - } else { - apiId = null; - for (NDependency dependency : descriptor.getDependencies()) { - if (dependency.toId().getShortName().equals(NConstants.Ids.NUTS_API) - && NDependencyScopes.isCompileScope(dependency.getScope())) { - apiId0 = dependency.toId().getLongId(); + if (getId().getShortName().equals(NConstants.Ids.NUTS_API)) { + // + } else { + apiId = null; + for (NDependency dependency : descriptor.getDependencies()) { + if (dependency.toId().getShortName().equals(NConstants.Ids.NUTS_API) + && NDependencyScopes.isCompileScope(dependency.getScope())) { + apiId0 = dependency.toId().getLongId(); + } } - } - if (apiId0 != null) { - if (getId().getShortName().equals(NConstants.Ids.NUTS_RUNTIME)) { - apiId = apiId0; - } else if (descriptor.getIdType() == NIdType.RUNTIME) { - apiId = apiId0; - } else if (descriptor.getIdType() == NIdType.EXTENSION) { - apiId = apiId0; - } else if (descriptor.getIdType() == NIdType.COMPANION) { - apiId = apiId0; + if (apiId0 != null) { + if (getId().getShortName().equals(NConstants.Ids.NUTS_RUNTIME)) { + apiId = apiId0; + } else if (descriptor.getIdType() == NIdType.RUNTIME) { + apiId = apiId0; + } else if (descriptor.getIdType() == NIdType.EXTENSION) { + apiId = apiId0; + } else if (descriptor.getIdType() == NIdType.COMPANION) { + apiId = apiId0; + } } } + DefaultNDefinition result = new DefaultNDefinition( + repo.getUuid(), + repo.getName(), + newId.getLongId(), + descriptor, + null, + null, + apiId, + null, + session + ); + String fRepoUuid = repo.getUuid(); + String fRepoName = repo.getName(); + NId fApiId = apiId; + NInstalledRepository installedRepository = dws.getInstalledRepository(); + CachedSupplier repositoryUuid = DefaultCachedSupplier.ofMem(() -> fRepoUuid, null); + CachedSupplier repositoryName = DefaultCachedSupplier.ofMem(() -> fRepoName, null); + CachedSupplier capiId = DefaultCachedSupplier.ofMem(() -> fApiId, null); + CachedSupplier cdescriptor = DefaultCachedSupplier.ofMem(() -> descriptor, null); + CachedSupplier content = + DefaultCachedSupplier.of( + withCache ? CachedSupplier.NCacheLevel.STORE : CachedSupplier.NCacheLevel.NONE, + NPath.class, + NLocationKey.ofCache(id, "contentPath", fRepoUuid), + new NContentDefaultLocationSupplier(id, result, location, nutsFetchModes, installedRepository, + descTracker, + session), + new DefaultCachedSupplier.SimpleCacheValidator<>(session), + session + ); + CachedSupplier effectiveDescriptor = DefaultCachedSupplier.of(withCache ? CachedSupplier.NCacheLevel.STORE : CachedSupplier.NCacheLevel.MEM, NDescriptor.class, NLocationKey.ofCache(id, "effective-descriptor", fRepoUuid), + new EffectiveDescriptorSupplier(dws, cdescriptor, content, id) + , new DefaultCachedSupplier.SimpleCacheValidator<>(session), session + ); + CachedSupplier dependencies = DefaultCachedSupplier.of(withCache ? CachedSupplier.NCacheLevel.STORE : CachedSupplier.NCacheLevel.MEM, NDependencies.class, NLocationKey.ofCache(id, "dependencies", fRepoUuid), + new DependenciesSupplier(id, result, effectiveDescriptor, session), new DefaultCachedSupplier.SimpleCacheValidator<>(session), session); + CachedSupplier install = DefaultCachedSupplier.ofNone(new InstallSupplierSupplier(installedRepository, id)); + return new DefaultNDefinitionRef(repositoryUuid, repositoryName, id.getLongId(), cdescriptor, content, install, capiId, + dependencies, effectiveDescriptor, + session); } - - DefaultNDefinition result = new DefaultNDefinition( - repo.getUuid(), - repo.getName(), - newId.getLongId(), - descriptor, - null, - null, - apiId, session - ); - if (withCache) { - try { - elem.json().setValue(result) - .setNtf(false).print(cachePath); - } catch (Exception ex) { - // + throw new NNotFoundException(session, id, new NNotFoundException.NIdInvalidDependency[0], new NNotFoundException.NIdInvalidLocation[]{ + new NNotFoundException.NIdInvalidLocation(repo.getName(), null, id + " not found") + }, null); + }; + DefaultCachedSupplier.SimpleCacheValidator validator = new DefaultCachedSupplier.SimpleCacheValidator(session) { + @Override + public boolean isValidValue(NDefinition d) { + NRepositories rr = NRepositories.of(session.copy().setTransitive(true)); + NRepository repositoryById = rr.findRepositoryById(d.getRepositoryUuid()).orNull(); + NRepository repositoryByName = rr.findRepositoryByName(d.getRepositoryName()).orNull(); + if (repositoryById == null || repositoryByName == null) { + //this is invalid cache! + return false; + } else { + NLogUtils.traceMessage(_LOG(getSession()), nutsFetchModes, id.getLongId(), NLogVerb.CACHE, "fetch definition", 0); + return true; } } - return result; - } - throw new NNotFoundException(session, id, new NNotFoundException.NIdInvalidDependency[0], new NNotFoundException.NIdInvalidLocation[]{ - new NNotFoundException.NIdInvalidLocation(repo.getName(), null, id + " not found") - }, null); + }; + return DefaultCachedSupplier.of( + withCache ? CachedSupplier.NCacheLevel.MEM : CachedSupplier.NCacheLevel.NONE, + NDefinition.class, + NLocationKey.ofCache(id, "def", repo.getUuid()), supplier, validator, + session + ).getValue(); } public static class ScopePlusOptionsCache { @@ -590,4 +493,251 @@ public int keyHashCode() { return s * 31 + (optional == null ? 0 : optional.hashCode()); } } + + private class NContentCustomLocationSupplier implements Supplier { + CachedSupplier s; + NPath copyTo; + DefaultNDefinition foundDefinition; + + public NContentCustomLocationSupplier(NId id, DefaultNDefinition foundDefinition, + NRepositoryAndFetchMode successfulDescriptorLocation, + NFetchStrategy nutsFetchModes, + NPath copyTo, + NInstalledRepository installedRepository, + NRepositoryAndFetchModeTracker descTracker, + String repoUuid, + DefaultCachedSupplier.CacheValidator cacheValidator, + NSession session, boolean enableCache) { + NContentDefaultLocationSupplier s0 = new NContentDefaultLocationSupplier(id, foundDefinition, successfulDescriptorLocation, nutsFetchModes, installedRepository, + descTracker, + session); + this.foundDefinition = foundDefinition; + this.copyTo = copyTo; + s = enableCache ? + DefaultCachedSupplier.ofStore( + NPath.class, + NLocationKey.ofCache(id, "contentPath", repoUuid), + s0, + cacheValidator, + session + ) : DefaultCachedSupplier.ofMem(s0, cacheValidator); + } + + @Override + public NPath get() { + if (copyTo == null) { + return s.getValue(); + } else { + NPath v = s.getValue(); + if (v != null) { + NPath copyTo2 = copyTo; + if (copyTo != null && copyTo.isDirectory()) { + NId id1 = CoreNIdUtils.createContentFaceId(foundDefinition.getId(), foundDefinition.getDescriptor(), session); + copyTo2 = copyTo.resolve(NLocations.of(session).getDefaultIdFilename(id1)); + } + v.copyTo(copyTo2); + return copyTo2; + } + return null; + } + } + } + + private class NContentDefaultLocationSupplier implements Supplier { + DefaultNDefinition foundDefinition; + NRepositoryAndFetchMode successfulDescriptorLocation; + NFetchStrategy nutsFetchModes; + NInstalledRepository installedRepository; + NId id; + NSession session; + NRepositoryAndFetchModeTracker descTracker; + + public NContentDefaultLocationSupplier(NId id, DefaultNDefinition foundDefinition, NRepositoryAndFetchMode successfulDescriptorLocation, NFetchStrategy nutsFetchModes, NInstalledRepository installedRepository, + NRepositoryAndFetchModeTracker descTracker, + NSession session) { + this.id = id; + this.foundDefinition = foundDefinition; + this.successfulDescriptorLocation = successfulDescriptorLocation; + this.nutsFetchModes = nutsFetchModes; + this.installedRepository = installedRepository; + this.session = session; + this.descTracker = descTracker; + } + + @Override + public NPath get() { + if (!NDescriptorUtils.isNoContent(foundDefinition.getDescriptor())) { + List reasons = new ArrayList<>(); + boolean loadedFromInstallRepo = DefaultNInstalledRepository.INSTALLED_REPO_UUID.equals(successfulDescriptorLocation + .getRepository().getUuid()); + NId id1 = CoreNIdUtils.createContentFaceId(foundDefinition.getId(), foundDefinition.getDescriptor(), session); + +// boolean escalateMode = false; + NRepositoryAndFetchModeTracker contentTracker = new NRepositoryAndFetchModeTracker(descTracker.available()); + + NPath contentSuccessful = fetchContent(id1, foundDefinition, successfulDescriptorLocation, null, reasons, session); + NRepositoryAndFetchMode successfulContentLocation = null; + if (contentSuccessful != null) { + successfulContentLocation = successfulDescriptorLocation; + } else { + contentTracker.addFailure(successfulDescriptorLocation); + } + if (contentSuccessful == null && !loadedFromInstallRepo) { + if (successfulDescriptorLocation.getFetchMode() == NFetchMode.LOCAL) { + NRepositoryAndFetchMode finalSuccessfulDescriptorLocation = successfulDescriptorLocation; + NRepositoryAndFetchMode n = contentTracker.available().stream() + .filter(x -> x.getRepository().getUuid().equals(finalSuccessfulDescriptorLocation.getRepository().getUuid()) && + x.getFetchMode() == NFetchMode.REMOTE).findFirst().orElse(null); + if (n != null/* && contentTracker.accept(n)*/) { + contentSuccessful = fetchContent(id1, foundDefinition, n, null, reasons, session); + if (contentSuccessful != null) { + successfulContentLocation = n; + } else { + contentTracker.addFailure(n); + } + } + } + } + if (contentSuccessful == null) { + for (NRepositoryAndFetchMode repoAndMode : contentTracker.available()) { + contentSuccessful = fetchContent(id1, foundDefinition, repoAndMode, null, reasons, session); + if (contentSuccessful != null) { + successfulContentLocation = repoAndMode; + break; + } else { + contentTracker.addFailure(repoAndMode); + } + } + } + if (contentSuccessful != null) { + if (loadedFromInstallRepo && successfulContentLocation != successfulDescriptorLocation) { + //this happens if the jar content is no more installed while its descriptor is still installed. + NRepositorySPI installedRepositorySPI = NWorkspaceUtils.of(session).repoSPI(installedRepository); + installedRepositorySPI.deploy() + .setId(foundDefinition.getId()) + .setDescriptor(foundDefinition.getDescriptor()) + .setSession(this.session.copy().setConfirm(NConfirmationMode.YES)) + //.setFetchMode(mode) + .setContent(foundDefinition.getContent().get(session)) + .run(); + + } + } + if (contentSuccessful == null /*&& includedRemote*/) { + NLogUtils.traceMessage(_LOG(session), nutsFetchModes, id.getLongId(), NLogVerb.FAIL, + "fetched descriptor but failed to fetch artifact binaries", 0); + } + return contentSuccessful; + } + return null; + } + + protected NPath fetchContent(NId id1, DefaultNDefinition foundDefinition, NRepositoryAndFetchMode repo, Path copyTo, List reasons, NSession session) { + NRepositorySPI repoSPI = NWorkspaceUtils.of(session).repoSPI(repo.getRepository()); + try { + NPath content = repoSPI.fetchContent() + .setId(id1).setDescriptor(foundDefinition.getDescriptor()) + .setLocalPath(copyTo == null ? null : copyTo.toString()) + .setSession(session) + .setFetchMode(repo.getFetchMode()) + .getResult(); + if (content != null) { + return content; + } + } catch (NNotFoundException ex) { + reasons.add(ex); + // + } + return null; + } + } + + private class EffectiveDescriptorSupplier implements Supplier { + private final NWorkspaceExt dws; + private final CachedSupplier descriptor; + private final CachedSupplier contentSupplier; + private final NId id; + + public EffectiveDescriptorSupplier(NWorkspaceExt dws, CachedSupplier descriptor, CachedSupplier contentSupplier, NId id) { + this.dws = dws; + this.descriptor = descriptor; + this.contentSupplier = contentSupplier; + this.id = id; + } + + @Override + public NDescriptor get() { + try { + NDescriptor d = dws.resolveEffectiveDescriptor(descriptor.getValue(), session); + NPath path = contentSupplier.getValue(); + if (path != null) { + d = resolveExecProperties(d, path); + } + return d; + } catch (NNotFoundException ex) { + //ignore + _LOGOP(getSession()).level(Level.WARNING).verb(NLogVerb.WARNING) + .log(NMsg.ofJ("artifact descriptor found, but one of its parents or dependencies is not: {0} : missing {1}", id, + ex.getId())); + } + return null; + } + } + + private class DependenciesSupplier implements Supplier { + private final NId id; + private final DefaultNDefinition d; + private final CachedSupplier effectiveDescriptor; + private final NSession session; + + public DependenciesSupplier(NId id, DefaultNDefinition d, CachedSupplier effectiveDescriptor, NSession session) { + this.id = id; + this.d = d; + this.effectiveDescriptor = effectiveDescriptor; + this.session = session; + } + + @Override + public NDependencies get() { + DefaultNDefinition nd = d; + if (d.getEffectiveDescriptor().isNotPresent()) { + NDescriptor descriptorValue = effectiveDescriptor.getValue(); + nd = new DefaultNDefinition( + d.getRepositoryUuid(), d.getRepositoryName(), + d.getId(), + d.getDescriptor(), + d.getContent().orNull(), + d.getInstallInformation().orNull(), + d.getApiId(), + descriptorValue, + session + ); + } + return NDependencySolver.of(getSession()) + .setFilter(buildActualDependencyFilter()) + .add(id.toDependency(), nd) + .solve(); + } + } + + private class InstallSupplierSupplier implements Supplier { + private final NInstalledRepository installedRepository; + private final NId id; + + public InstallSupplierSupplier(NInstalledRepository installedRepository, NId id) { + this.installedRepository = installedRepository; + this.id = id; + } + + @Override + public NInstallInformation get() { + NInstallInformation ii = installedRepository.getInstallInformation(id, session); + if (ii != null) { +// ((DefaultNInstalledRepository) (dws.getInstalledRepository())).updateInstallInfoConfigInstallDate(id, Instant.now(), session); + return ii; + } else { + return DefaultNInstallInfo.notInstalled(id); + } + } + } } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/info/DefaultNInfoCommand.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/info/DefaultNInfoCommand.java index d89910898..557b4ebad 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/info/DefaultNInfoCommand.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/info/DefaultNInfoCommand.java @@ -694,6 +694,7 @@ private Map buildRepoRepoMap(NRepository repo, boolean deep, Str ); props.put(key(prefix, "speed"), (repo.config().getSpeed())); props.put(key(prefix, "enabled"), (repo.config().isEnabled())); + props.put(key(prefix, "active"), (repo.isEnabled(session))); props.put(key(prefix, "index-enabled"), (repo.config().isIndexEnabled())); props.put(key(prefix, "index-subscribed"), (repo.config().setSession(getSession()).isIndexSubscribed())); props.put(key(prefix, "location"), repo.config().getLocation()); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/search/AbstractNSearchCommand.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/search/AbstractNSearchCommand.java index 59d24c5cc..eb90678c5 100755 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/search/AbstractNSearchCommand.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/search/AbstractNSearchCommand.java @@ -1033,7 +1033,6 @@ public String toString() { + ", inlineDependencies=" + isInlineDependencies() + ", dependencies=" + isDependencies() + ", effective=" + isEffective() - + ", location=" + getLocation() + ", displayOptions=" + getDisplayOptions() + ", comparator=" + getComparator() + ", dependencyFilter=" + getDependencyFilter() diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/settings/util/SettingsRepoUtils.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/settings/util/SettingsRepoUtils.java index b198810d6..bebc390d7 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/settings/util/SettingsRepoUtils.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/cmd/settings/util/SettingsRepoUtils.java @@ -7,8 +7,9 @@ public class SettingsRepoUtils { public static void showRepo(NSession session, NRepository repository, String prefix) { + boolean active = repository.isEnabled(session); boolean enabled = repository.config().isEnabled(); - String disabledString = enabled ? "" : " "; + String disabledString = active ? "" : enabled ? "" : " "; NPrintStream out = session.out(); out.print(prefix); NTexts factory = NTexts.of(session); diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/DefaultNWorkspaceConfigModel.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/DefaultNWorkspaceConfigModel.java index b829bdbef..bcbb2c39e 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/DefaultNWorkspaceConfigModel.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/DefaultNWorkspaceConfigModel.java @@ -91,7 +91,7 @@ * @author thevpc */ public class DefaultNWorkspaceConfigModel { - private static Pattern PRELOAD_EXTENSION_PATH_PATTERN = Pattern.compile("^(?[a-z][a-z0-9_-]*):.*"); + private static Pattern PRELOAD_EXTENSION_PATH_PATTERN = Pattern.compile("^(?[a-z][a-z0-9_-]*):.*"); private final DefaultNWorkspace ws; private final Map configUsers = new LinkedHashMap<>(); @@ -125,9 +125,9 @@ public class DefaultNWorkspaceConfigModel { // private NutsRepositorySelector[] parsedBootRepositoriesArr; private ExecutorService executorService; private NSessionTerminal terminal; - private Map protocolToExtensionMap=new HashMap<>( + private Map protocolToExtensionMap = new HashMap<>( NMaps.of( - "ssh",NId.of("net.thevpc.nuts.ext:next-ssh").get() + "ssh", NId.of("net.thevpc.nuts.ext:next-ssh").get() ) ); // private final NutsLogger LOG; @@ -1103,7 +1103,7 @@ public void collect(NClassLoaderNode n, LinkedHashMap } public NBootDef fetchBootDef(NId id, boolean content, NSession session) { - NDefinition nd = NFetchCommand.of(id,session) + NDefinition nd = NFetchCommand.of(id, session) .setDependencies(true).setContent(content) .setDependencyFilter(NDependencyFilters.of(session).byRunnable()) .setFailFast(false).getResultDefinition(); @@ -1214,7 +1214,7 @@ private boolean deployToInstalledRepository(Path tmp, NSession session) { descriptor.getId(), descriptor, NPath.of(tmp, session).setUserCache(true).setUserTemporary(true), new DefaultNInstallInfo(descriptor.getId(), NInstallStatus.NONE, null, null, null, null, null, null, false, false), - null, session + null, null, session ); ins.install(b, session); return true; @@ -1499,10 +1499,10 @@ public NPath resolve(String path, NSession session, ClassLoader classLoader) { ClassLoader finalClassLoader = classLoader; Matcher m = PRELOAD_EXTENSION_PATH_PATTERN.matcher(path); - if(m.find()){ + if (m.find()) { String protocol = m.group("protocol"); NId eid = protocolToExtensionMap.get(protocol); - if(eid!=null){ + if (eid != null) { NExtensions.of(session).loadExtension(eid); } } diff --git a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/NWorkspaceModel.java b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/NWorkspaceModel.java index 74ccd1472..c11b1b89b 100644 --- a/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/NWorkspaceModel.java +++ b/core/nuts-runtime/src/main/java/net/thevpc/nuts/runtime/standalone/workspace/config/NWorkspaceModel.java @@ -2,7 +2,10 @@ import net.thevpc.nuts.*; import net.thevpc.nuts.boot.NBootOptions; +import net.thevpc.nuts.runtime.standalone.NWsConfDB; import net.thevpc.nuts.runtime.standalone.event.DefaultNWorkspaceEventModel; +import net.thevpc.nuts.runtime.standalone.io.cache.CachedSupplier; +import net.thevpc.nuts.runtime.standalone.util.collections.LRUMap; import net.thevpc.nuts.runtime.standalone.util.collections.NPropertiesHolder; import net.thevpc.nuts.runtime.standalone.util.filters.DefaultNFilterModel; import net.thevpc.nuts.runtime.standalone.text.DefaultNTextManagerModel; @@ -44,12 +47,15 @@ public class NWorkspaceModel { public DefaultCustomCommandsModel aliasesModel; public DefaultImportModel importModel; public String apiDigest; + public String installationDigest; public SafeRecommendationConnector recomm =new SafeRecommendationConnector(new SimpleRecommendationConnector()); public List recommendedCompanions=new ArrayList<>(); public NPropertiesHolder properties = new NPropertiesHolder(); public NVersion askedApiVersion; public NId askedRuntimeId; public NBootOptions bOption0; + public NWsConfDB confDB=new NWsConfDB(); + public LRUMap> cachedDefs=new LRUMap<>(100); public NWorkspaceModel(NWorkspace ws, NBootOptions bOption0) { this.ws = ws; diff --git a/core/nuts/src/main/java/net/thevpc/nuts/NApplications.java b/core/nuts/src/main/java/net/thevpc/nuts/NApplications.java index f983e921a..6b3ef1c2c 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/NApplications.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/NApplications.java @@ -170,7 +170,7 @@ public static T createApplicationInstance(Class appT } catch (InvocationTargetException ex) { throw new NBootException(NMsg.ofC("invocation exception for %s", appType.getName()), ex); } - throw new NBootException(NMsg.ofC("missing application constructor one of : \n\t static createApplicationInstance(NutsSession,String[])\n\t Constructor(NutsSession,String[])\n\t Constructor()", appType.getName())); + throw new NBootException(NMsg.ofC("missing application constructor for %s from of : \n\t static createApplicationInstance(NutsSession,String[])\n\t Constructor(NutsSession,String[])\n\t Constructor()", appType.getName())); } /** diff --git a/core/nuts/src/main/java/net/thevpc/nuts/NFetchCommand.java b/core/nuts/src/main/java/net/thevpc/nuts/NFetchCommand.java index ce053c3da..042541cdb 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/NFetchCommand.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/NFetchCommand.java @@ -67,13 +67,6 @@ static NFetchCommand ofNutsRuntime(NSession session) { // Setters //////////////////////////////////////////////////////// - /** - * unset location to store to fetched id and fall back to default location. - * - * @return {@code this} instance - */ - NFetchCommand setDefaultLocation(); - /** * when true, NutsNotFoundException instances are ignored * @@ -177,7 +170,7 @@ static NFetchCommand ofNutsRuntime(NSession session) { * * @return result as content path */ - Path getResultPath(); + NPath getResultPath(); /** * create copy (new instance) of {@code this} command @@ -260,23 +253,6 @@ static NFetchCommand ofNutsRuntime(NSession session) { */ NFetchCommand clearScopes(); - /** - * get locating where to fetch the artifact. If the location is a folder, a - * new name will be generated. - * - * @return location path - */ - Path getLocation(); - - /** - * set locating where to fetch the artifact. If the location is a folder, a - * new name will be generated. - * - * @param fileOrFolder path to store to - * @return {@code this} instance - */ - NFetchCommand setLocation(Path fileOrFolder); - /** * dependencies scope filters * diff --git a/core/nuts/src/main/java/net/thevpc/nuts/NSearchCommand.java b/core/nuts/src/main/java/net/thevpc/nuts/NSearchCommand.java index ec788dabb..d3727f0b5 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/NSearchCommand.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/NSearchCommand.java @@ -797,31 +797,7 @@ static NSearchCommand of(NSession session) { NSearchCommand removeScope(NDependencyScopePattern scope); /** - * unset location to store to fetched id and fall back to default location. - * - * @return {@code this} instance - */ - NSearchCommand setDefaultLocation(); - - /** - * get locating where to fetch the artifact. If the location is a folder, a - * new name will be generated. - * - * @return location path - */ - Path getLocation(); - - /** - * set locating where to fetch the artifact. If the location is a folder, a - * new name will be generated. - * - * @param fileOrFolder path to store to - * @return {@code this} instance - */ - NSearchCommand setLocation(Path fileOrFolder); - - /** - * scope filter filter. applicable with + * scope filter. applicable with * {@link #setInlineDependencies(boolean)} * * @return optional filter diff --git a/core/nuts/src/main/java/net/thevpc/nuts/format/NFormattable.java b/core/nuts/src/main/java/net/thevpc/nuts/format/NFormattable.java index 0d818f67e..8bd8869f8 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/format/NFormattable.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/format/NFormattable.java @@ -32,7 +32,7 @@ /** * @app.category Format */ -public interface NFormattable { +public interface NFormattable extends NStringFormattable { NFormat formatter(NSession session); default NString format(NSession session) { diff --git a/core/nuts/src/main/java/net/thevpc/nuts/format/NMsgFormattable.java b/core/nuts/src/main/java/net/thevpc/nuts/format/NMsgFormattable.java new file mode 100644 index 000000000..d635145d9 --- /dev/null +++ b/core/nuts/src/main/java/net/thevpc/nuts/format/NMsgFormattable.java @@ -0,0 +1,38 @@ +/** + * ==================================================================== + * Nuts : Network Updatable Things Service + * (universal package manager) + *
+ * is a new Open Source Package Manager to help install packages + * and libraries for runtime execution. Nuts is the ultimate companion for + * maven (and other build managers) as it helps installing all package + * dependencies at runtime. Nuts is not tied to java and is a good choice + * to share shell scripts and other 'things' . Its based on an extensible + * architecture to help supporting a large range of sub managers / repositories. + * + *
+ *

+ * Copyright [2020] [thevpc] + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain a + * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + *
+ * ==================================================================== + */ +package net.thevpc.nuts.format; + +import net.thevpc.nuts.NSession; +import net.thevpc.nuts.text.NString; +import net.thevpc.nuts.util.NMsg; + +/** + * @app.category Format + */ +public interface NMsgFormattable { + NMsg toMsg(); +} diff --git a/core/nuts/src/main/java/net/thevpc/nuts/format/NStringFormattable.java b/core/nuts/src/main/java/net/thevpc/nuts/format/NStringFormattable.java new file mode 100644 index 000000000..a54a3e1bc --- /dev/null +++ b/core/nuts/src/main/java/net/thevpc/nuts/format/NStringFormattable.java @@ -0,0 +1,37 @@ +/** + * ==================================================================== + * Nuts : Network Updatable Things Service + * (universal package manager) + *
+ * is a new Open Source Package Manager to help install packages + * and libraries for runtime execution. Nuts is the ultimate companion for + * maven (and other build managers) as it helps installing all package + * dependencies at runtime. Nuts is not tied to java and is a good choice + * to share shell scripts and other 'things' . Its based on an extensible + * architecture to help supporting a large range of sub managers / repositories. + * + *
+ *

+ * Copyright [2020] [thevpc] + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. You may obtain a + * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific language + * governing permissions and limitations under the License. + *
+ * ==================================================================== + */ +package net.thevpc.nuts.format; + +import net.thevpc.nuts.NSession; +import net.thevpc.nuts.text.NString; + +/** + * @app.category Format + */ +public interface NStringFormattable { + NString format(NSession session); +} diff --git a/core/nuts/src/main/java/net/thevpc/nuts/io/NIO.java b/core/nuts/src/main/java/net/thevpc/nuts/io/NIO.java index 7c2249613..2e8fa2cb3 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/io/NIO.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/io/NIO.java @@ -65,10 +65,12 @@ static NIO of(NSession session) { * @return {@code mode} supporting PrintStream */ NPrintStream ofPrintStream(OutputStream out, NTerminalMode mode, NSystemTerminalBase terminal); + NPrintStream ofPrintStream(OutputStream out, NTerminalMode mode); NPrintStream ofPrintStream(OutputStream out); NPrintStream ofPrintStream(Writer out, NTerminalMode mode, NSystemTerminalBase terminal); + NPrintStream ofPrintStream(Writer out, NTerminalMode mode); NPrintStream ofPrintStream(NPath out); diff --git a/core/nuts/src/main/java/net/thevpc/nuts/io/NPrintStream.java b/core/nuts/src/main/java/net/thevpc/nuts/io/NPrintStream.java index 333fceb7b..755a9a8c6 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/io/NPrintStream.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/io/NPrintStream.java @@ -80,6 +80,10 @@ static NPrintStream of(OutputStream out, NTerminalMode mode, NSystemTerminalBase return NIO.of(session).ofPrintStream(out, mode, terminal); } + static NPrintStream of(OutputStream out, NTerminalMode mode, NSession session) { + return NIO.of(session).ofPrintStream(out, mode); + } + static NPrintStream of(Writer out, NSession session) { return NIO.of(session).ofPrintStream(out); } diff --git a/core/nuts/src/main/java/net/thevpc/nuts/reserved/NReservedUtils.java b/core/nuts/src/main/java/net/thevpc/nuts/reserved/NReservedUtils.java index 103f5d4af..ab78fe0ec 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/reserved/NReservedUtils.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/reserved/NReservedUtils.java @@ -608,6 +608,9 @@ public static NOptional parseId(String nutsId) { } private static void setIdProperty(String key, String value, NIdBuilder builder, NEnvConditionBuilder sb, Map props) { + if (key == null) { + return; + } switch (key) { case NConstants.IdProperties.CLASSIFIER: { builder.setClassifier(value); diff --git a/core/nuts/src/main/java/net/thevpc/nuts/util/NMsg.java b/core/nuts/src/main/java/net/thevpc/nuts/util/NMsg.java index 1d1632241..749908e50 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/util/NMsg.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/util/NMsg.java @@ -26,11 +26,11 @@ */ package net.thevpc.nuts.util; -import net.thevpc.nuts.text.NString; +import net.thevpc.nuts.NIllegalArgumentException; +import net.thevpc.nuts.NSession; +import net.thevpc.nuts.NUnsupportedEnumException; +import net.thevpc.nuts.text.*; import net.thevpc.nuts.reserved.NReservedLangUtils; -import net.thevpc.nuts.text.NTextFormatType; -import net.thevpc.nuts.text.NTextStyle; -import net.thevpc.nuts.text.NTextStyles; import java.text.MessageFormat; import java.util.*; @@ -130,6 +130,13 @@ public static NMsg ofCode(String text) { return of(NTextFormatType.CODE, text, NO_PARAMS, null, null, null); } + public static NMsg ofStringLiteral(String literal) { + if(literal==null){ + return NMsg.ofStyled("null",NTextStyle.primary1()); + } + return NMsg.ofStyled(NStringUtils.formatStringLiteral(literal),NTextStyle.string()); + } + public static NMsg ofStyled(String message, NTextStyle style) { return of(NTextFormatType.STYLED, message, NO_PARAMS, style == null ? null : NTextStyles.of(style), null, null); } diff --git a/core/nuts/src/main/java/net/thevpc/nuts/util/NStringMapFormat.java b/core/nuts/src/main/java/net/thevpc/nuts/util/NStringMapFormat.java index e5478c23f..a0ae1299d 100644 --- a/core/nuts/src/main/java/net/thevpc/nuts/util/NStringMapFormat.java +++ b/core/nuts/src/main/java/net/thevpc/nuts/util/NStringMapFormat.java @@ -32,8 +32,8 @@ import java.util.*; public class NStringMapFormat { - public static NStringMapFormat URL_FORMAT = NStringMapFormat.of("=", "&", "?", true); - public static NStringMapFormat COMMA_FORMAT = NStringMapFormat.of("=", ",", "", true); + public static NStringMapFormat URL_FORMAT = NStringMapFormat.of("=", "&", "\\", true); + public static NStringMapFormat COMMA_FORMAT = NStringMapFormat.of("=", ",", "\\", true); public static NStringMapFormat DEFAULT = URL_FORMAT; private final String equalsChars; @@ -125,10 +125,16 @@ public TokenConfig setEscapeChars(String escapeChars) { private static class Token { TokenType type; String value; + String image; public Token(TokenType type, String value) { + this(type, value, value); + } + + public Token(TokenType type, String value, String image) { this.type = type; this.value = value; + this.image = image; } } @@ -136,7 +142,8 @@ private static Token readToken(PushbackReader reader, TokenConfig conf) throws I String escapedTokens = conf.getEscapeChars(); String eqChars = conf.getEqChars(); String sepChars = conf.getSepChars(); - StringBuilder result = new StringBuilder(); + StringBuilder value = new StringBuilder(); + StringBuilder image = new StringBuilder(); int r = reader.read(); if (r == -1) { return null; @@ -160,43 +167,46 @@ private static Token readToken(PushbackReader reader, TokenConfig conf) throws I } if (r == '\"' || r == '\'') { char cr = (char) r; + image.append(cr); while (true) { r = reader.read(); if (r == -1) { throw new RuntimeException("Expected " + cr); } + image.append(cr); if (r == cr) { - return new Token(cr == '\"' ? TokenType.SIMPLE_QUOTED : TokenType.DOUBLE_QUOTED, result.toString()); + return new Token(cr == '\"' ? TokenType.SIMPLE_QUOTED : TokenType.DOUBLE_QUOTED, value.toString()); } if (r == '\\') { r = reader.read(); if (r == -1) { throw new RuntimeException("Expected " + cr); } + image.append((char) r); switch ((char) r) { case 'n': { - result.append('\n'); + value.append('\n'); break; } case 'r': { - result.append('\r'); + value.append('\r'); break; } case 'f': { - result.append('\f'); + value.append('\f'); break; } case 't': { - result.append('\t'); + value.append('\t'); break; } default: { - result.append('\\'); - result.append((char) r); + value.append('\\'); + value.append((char) r); } } } else { - result.append((char) r); + value.append((char) r); } } } else { @@ -204,53 +214,62 @@ private static Token readToken(PushbackReader reader, TokenConfig conf) throws I while (true) { r = reader.read(); if (r < 0) { - return new Token(TokenType.WORD, result.toString()); + return new Token(TokenType.WORD, value.toString(), image.toString()); } char cr = (char) r; - if (r == '\\') { + if (escapedTokens.indexOf(cr) >= 0) { + image.append(cr); r = reader.read(); if (r == -1) { - result.append(cr); - return new Token(TokenType.WORD, result.toString()); + value.append(cr); + return new Token(TokenType.WORD, value.toString(), image.toString()); } else { - if (escapedTokens.indexOf(cr) >= 0) { - result.append(cr); + cr = (char) r; + +// r = reader.read(); +// if (r == -1) { +// value.append(cr); +// return new Token(TokenType.WORD, value.toString(),image.toString()); +// } +// cr = (char) r; + image.append(cr); + if (escapedTokens.indexOf(cr) >= 0 || isWhitespace(cr) || eqChars.indexOf(cr) >= 0 || sepChars.indexOf(cr) >= 0) { + value.append(cr); } else { switch ((char) r) { case ' ': { - result.append(' '); + value.append(' '); break; } case 'n': { - result.append('\n'); + value.append('\n'); break; } case 'r': { - result.append('\r'); + value.append('\r'); break; } case 'f': { - result.append('\f'); + value.append('\f'); break; } case 't': { - result.append('\t'); + value.append('\t'); break; } default: { - result.append('\\'); - result.append(cr); + value.append(cr); + value.append((char)r); } } } } - } else if (escapedTokens.indexOf(cr) >= 0) { - result.append(cr); } else if (isWhitespace(cr) || eqChars.indexOf(cr) >= 0 || sepChars.indexOf(cr) >= 0) { reader.unread(cr); - return new Token(TokenType.WORD, result.toString()); + return new Token(TokenType.WORD, value.toString(), image.toString()); } else { - result.append(cr); + value.append(cr); + image.append(cr); } } } diff --git a/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/AnsiTermPane.java b/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/AnsiTermPane.java index e7422dfe9..04161405e 100644 --- a/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/AnsiTermPane.java +++ b/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/AnsiTermPane.java @@ -13,8 +13,8 @@ * thanks to https://stackoverflow.com/questions/6913983/jtextpane-removing-first-line */ public class AnsiTermPane extends JTextPane { - public static Color colorForeground = Color.BLACK;//cReset; - public static Color colorBackground = null;//cReset; + // public static Color colorForeground = Color.BLACK;//cReset; +// public static Color colorBackground = null;//cReset; public Color D_Black = Color.getHSBColor(0.000f, 0.000f, 0.000f); public Color D_Red = Color.getHSBColor(0.000f, 1.000f, 0.502f); public Color D_Blue = Color.getHSBColor(0.667f, 1.000f, 0.502f); @@ -31,7 +31,8 @@ public class AnsiTermPane extends JTextPane { public Color B_Yellow = Color.getHSBColor(0.167f, 1.000f, 1.000f).darker(); public Color B_Cyan = Color.getHSBColor(0.500f, 1.000f, 1.000f); public Color B_White = Color.getHSBColor(0.000f, 0.000f, 1.000f); - public Color cReset = Color.BLACK;//Color.getHSBColor(0.000f, 0.000f, 1.000f); + public Color cResetForeground = Color.BLACK;//Color.getHSBColor(0.000f, 0.000f, 1.000f); + public Color cResetBackground = Color.WHITE;//Color.getHSBColor(0.000f, 0.000f, 1.000f); public Color[] COLS = new Color[]{ D_Black, D_Red, D_Green, D_Yellow, D_Blue, D_Magenta, D_Cyan, D_White, B_Black, B_Red, B_Green, B_Yellow, B_Blue, B_Magenta, B_Cyan, B_White, @@ -39,13 +40,15 @@ public class AnsiTermPane extends JTextPane { // public static Color colorCurrent = Color.WHITE;//cReset; String remaining = ""; PrintStream ps; + Style currentStyle = new Style() + .setForeColor(Color.BLACK); public AnsiTermPane(boolean darkMode) { setDarkMode(darkMode); } public String colorName(Color c) { - if (c.equals(cReset)) { + if (c.equals(cResetForeground)) { return "reset"; } if (c.equals(D_Black)) { @@ -99,12 +102,21 @@ public String colorName(Color c) { return "?"; } + public Style restStyle() { + return new Style().setForeColor(cResetForeground).setBackColor(cResetBackground); + } + + public void resetCurr() { + currentStyle = restStyle(); + } + public void setDarkMode(boolean darkMode) { - cReset = darkMode ? Color.WHITE : Color.BLACK; + cResetForeground = darkMode ? Color.WHITE : Color.BLACK; + cResetBackground = getBackground(); // setForeground(Color.WHITE); setFont(new Font("Courier New", Font.PLAIN, 14)); - setForeground(cReset); - colorForeground = cReset; + setForeground(cResetForeground); + resetCurr(); if (darkMode) { D_Blue = new Color(124, 124, 220); B_Blue = new Color(162, 162, 225); @@ -145,7 +157,7 @@ public Color color256(int c) { if (c < 16) { c = Math.abs(c) % COLS.length; if (c == 0) { - return cReset; + return cResetForeground; } else { return COLS[c]; } @@ -169,36 +181,116 @@ public Color color256(int c) { public void append(int c, String s) { - append(color256(c), s); + append(currentStyle.copy().setForeColor(color256(c)), s); } - public void append(Color c, String s) { + public void append(Style c, String s) { // System.out.println(">>"+colorName(c)+" : "+s); StyleContext sc = StyleContext.getDefaultStyleContext(); - AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c); + AttributeSet aset = SimpleAttributeSet.EMPTY; + aset = sc.addAttribute(aset, StyleConstants.Foreground, c.foreColor); + if (c.backColor != null) { + aset = sc.addAttribute(aset, StyleConstants.Background, c.backColor); + } + aset = sc.addAttribute(aset, StyleConstants.Underline, c.underline); + aset = sc.addAttribute(aset, StyleConstants.Bold, c.bold); + aset = sc.addAttribute(aset, StyleConstants.Italic, c.italic); + aset = sc.addAttribute(aset, StyleConstants.StrikeThrough, c.strikeThrough); int len = getDocument().getLength(); // same value as getText().length(); boolean editable = isEditable(); setEditable(true); setCaretPosition(len); // place caret at the end (with no selection) setCharacterAttributes(aset, false); - replaceSelection(s); // there is no selection, so inserts at caret + replaceSelection(s); + System.out.print(s);// there is no selection, so inserts at caret setEditable(editable); } + private static class Style implements Cloneable { + Color foreColor; + Color backColor; + boolean underline; + boolean bold; + boolean strikeThrough; + boolean italic; + + public Color getForeColor() { + return foreColor; + } + + public Style setForeColor(Color foreColor) { + this.foreColor = foreColor; + return this; + } + + public Color getBackColor() { + return backColor; + } + + public Style setBackColor(Color backColor) { + this.backColor = backColor; + return this; + } + + public boolean isUnderline() { + return underline; + } + + public Style setUnderline(boolean underline) { + this.underline = underline; + return this; + } + + public boolean isBold() { + return bold; + } + + public Style setBold(boolean bold) { + this.bold = bold; + return this; + } + + public boolean isStrikeThrough() { + return strikeThrough; + } + + public Style setStrikeThrough(boolean strikeThrough) { + this.strikeThrough = strikeThrough; + return this; + } + + public boolean isItalic() { + return italic; + } + + public Style setItalic(boolean italic) { + this.italic = italic; + return this; + } + + public Style copy() { + try { + return (Style) clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + } + public PrintStream asPrintStream() { if (ps == null) { ps = new PrintStream( new OutputStream() { @Override public void write(int b) throws IOException { - UI.withinGUI(()->{ + UI.withinGUI(() -> { appendANSI(String.valueOf((char) b)); }); } @Override public void write(byte[] b, int off, int len) throws IOException { - UI.withinGUI(()->{ + UI.withinGUI(() -> { appendANSI(new String(b, off, len)); }); } @@ -237,14 +329,14 @@ public void appendANSI(String s) { // convert ANSI color codes first if (addString.length() > 0) { aIndex = addString.indexOf("\u001B"); // find first escape if (aIndex == -1) { // no escape/color change in this string, so just send it with current color - append(colorForeground, addString); + append(currentStyle, addString); return; } // otherwise There is an escape character in the string, so we must process it if (aIndex > 0) { // Escape is not first char, so send text up to first escape tmpString = addString.substring(0, aIndex); - append(colorForeground, tmpString); + append(currentStyle, tmpString); aPos = aIndex; } // aPos is now at the beginning of the first escape sequence @@ -258,7 +350,7 @@ public void appendANSI(String s) { // convert ANSI color codes first continue; } else { tmpString = addString.substring(aPos, mIndex + 1); - getANSIColor(tmpString); + applyANSIColor(tmpString); } aPos = mIndex + 1; // now we have the color, send text that is in that color (up to next escape) @@ -267,7 +359,7 @@ public void appendANSI(String s) { // convert ANSI color codes first if (aIndex == -1) { // if that was the last sequence of the input, send remaining text tmpString = addString.substring(aPos); - append(colorForeground, tmpString); + append(currentStyle, tmpString); stillSearching = false; continue; // jump out of loop early, as the whole string has been sent now } @@ -275,13 +367,13 @@ public void appendANSI(String s) { // convert ANSI color codes first // there is another escape sequence, so send part of the string and prepare for the next tmpString = addString.substring(aPos, aIndex); aPos = aIndex; - append(colorForeground, tmpString); + append(currentStyle, tmpString); } // while there's text in the input buffer } } - public void getANSIColor(String ANSIColor) { + public void applyANSIColor(String ANSIColor) { Pattern p = Pattern.compile("\u001B\\[(?\\d+)(;(?\\d+)(;(?\\d+)(;(?\\d+)(;(?\\d+))?)?)?)?m"); Matcher m = p.matcher(ANSIColor); if (m.find()) { @@ -292,7 +384,24 @@ public void getANSIColor(String ANSIColor) { int e = m.group("e") == null ? -1 : Integer.parseInt(m.group("e")); switch (a) { case 0: { - colorForeground = color256(0); +// currentStyle=currentStyle.copy().setForeColor(color256(0)); + currentStyle = restStyle();// new Style().setForeColor(color256(0)); + break; + } + case 1: { + currentStyle = currentStyle.copy().setBold(true); + break; + } + case 3: { + currentStyle = currentStyle.copy().setItalic(true); + break; + } + case 4: { + currentStyle = currentStyle.copy().setUnderline(true); + break; + } + case 9: { + currentStyle = currentStyle.copy().setStrikeThrough(true); break; } case 30: @@ -303,20 +412,20 @@ public void getANSIColor(String ANSIColor) { case 35: case 36: case 37: { - colorForeground = color256(a - 30); + currentStyle = currentStyle.copy().setForeColor(color256(a - 30)); break; } case 38: { switch (b) { case 5: { - colorForeground = color256(c); + currentStyle = currentStyle.copy().setForeColor(color256(c)); break; } case 2: { int rr = valid255(c); int gg = valid255(d); int bb = valid255(e); - colorForeground = new Color(rr, gg, bb); + currentStyle = currentStyle.copy().setForeColor(new Color(rr, gg, bb)); break; } } @@ -326,9 +435,9 @@ public void getANSIColor(String ANSIColor) { switch (b) { case 5: { if (c == 0) { - colorBackground = null; + currentStyle = currentStyle.copy().setBackColor(null); } else { - colorBackground = color256(c); + currentStyle = currentStyle.copy().setBackColor(color256(c)); } break; } @@ -336,7 +445,7 @@ public void getANSIColor(String ANSIColor) { int rr = valid255(c); int gg = valid255(d); int bb = valid255(e); - colorBackground = new Color(rr, gg, bb); + currentStyle = currentStyle.copy().setBackColor(new Color(rr, gg, bb)); break; } } diff --git a/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/GBC.java b/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/GBC.java index 38214f400..54c1cc306 100644 --- a/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/GBC.java +++ b/libraries/nlib-swing/src/main/java/net/thevpc/nuts/lib/nswing/GBC.java @@ -3,7 +3,26 @@ import java.awt.*; public class GBC { - GridBagConstraints b = new GridBagConstraints(); + private int gridx; + private int gridy; + private int gridwidth; + private int gridheight; + + private double weightx; + private double weighty; + + private int anchor; + private int fill; + + private Insets insets; + + private int ipadx; + + private int ipady; + + public GBC() { + this.reset(); + } public static GBC of(int x, int y) { return of().at(x, y); @@ -14,34 +33,34 @@ public static GBC ofAt(int x, int y) { } public GBC ipad(int x, int y) { - b.ipadx = x; - b.ipady = y; + this.ipadx = x; + this.ipady = y; return this; } public GBC weightx(int x) { - b.weightx = x; + this.weightx = x; return this; } public GBC weighty(int y) { - b.weighty = y; + this.weighty = y; return this; } public GBC weight(int x) { - return weight(x,x); + return weight(x, x); } public GBC weight(int x, int y) { - b.weightx = x; - b.weighty = y; + this.weightx = x; + this.weighty = y; return this; } public GBC at(int x, int y) { - b.gridx = x; - b.gridy = y; + this.gridx = x; + this.gridy = y; return this; } @@ -50,28 +69,25 @@ public static GBC of() { } public GBC fillNone() { - b.fill = GridBagConstraints.NONE; + this.fill = GridBagConstraints.NONE; return this; } public GBC fillVertical() { - b.fill = GridBagConstraints.VERTICAL; + this.fill = GridBagConstraints.VERTICAL; return this; } public GBC fillHorizontal() { - b.fill = GridBagConstraints.HORIZONTAL; + this.fill = GridBagConstraints.HORIZONTAL; return this; } public GBC fillBoth() { - b.fill = GridBagConstraints.BOTH; + this.fill = GridBagConstraints.BOTH; return this; } - public GridBagConstraints build() { - return b; - } public GBC anchorWest() { return anchor(GridBagConstraints.WEST); @@ -96,42 +112,66 @@ public GBC anchorNorthWest() { public GBC anchorNorthEast() { return anchor(GridBagConstraints.NORTHEAST); } + public GBC anchorNorth() { return anchor(GridBagConstraints.NORTH); } + public GridBagConstraints moveNextColumn() { + GridBagConstraints g = build(); + this.nextColumn(); + return g; + } + + public GridBagConstraints moveNextLine() { + GridBagConstraints g = build(); + this.nextLine(); + return g; + } + + public GBC nextColumn() { + this.gridx += this.gridwidth; + return this; + } + + public GBC nextLine() { + this.gridx = 0; + this.gridy += this.gridheight; + return this; + } + public GBC anchor(int a) { - this.b.anchor = a; + this.anchor = a; return this; } public GBC colspanReminder() { - b.gridwidth = GridBagConstraints.REMAINDER; + this.gridwidth = GridBagConstraints.REMAINDER; return this; } public GBC colspanRelative() { - b.gridwidth = GridBagConstraints.RELATIVE; + this.gridwidth = GridBagConstraints.RELATIVE; return this; } public GBC colspan(int c) { - b.gridwidth = c; + this.gridwidth = c; return this; } public GBC rowspan(int c) { - b.gridheight = c; + this.gridheight = c; return this; } public GBC rowspanReminder() { - b.gridheight = GridBagConstraints.REMAINDER; + this.gridheight = GridBagConstraints.REMAINDER; return this; } public GBC rowspanRelative() { - b.gridheight = GridBagConstraints.RELATIVE; + this.gridheight = GridBagConstraints.RELATIVE; return this; } @@ -139,7 +179,7 @@ public GBC insets(int v, int h) { return insets(new Insets(v, h, v, h)); } - public GBC insets(int top,int left,int bottom,int right) { + public GBC insets(int top, int left, int bottom, int right) { return insets(new Insets(top, left, bottom, right)); } @@ -148,8 +188,83 @@ public GBC insets(int i) { } public GBC insets(Insets i) { - b.insets = i; + this.insets = i; return this; } + //////////////////////////////////////// + + + public GridBagConstraints build() { + GridBagConstraints b = new GridBagConstraints(); + b.gridx = this.gridx; + b.gridy = this.gridy; + b.gridwidth = this.gridwidth; + b.gridheight = this.gridheight; + b.weightx = this.weightx; + b.weighty = this.weighty; + b.anchor = this.anchor; + b.fill = this.fill; + b.insets = copyInsets(this.insets); + b.ipadx = this.ipadx; + b.ipady = this.ipady; + return b; + } + + public GBC reset() { + this.gridx = 0; + this.gridy = 0; +// this.gridx = GridBagConstraints.RELATIVE; +// this.gridy = GridBagConstraints.RELATIVE; + this.gridwidth = 1; + this.gridheight = 1; + this.weightx = 0; + this.weighty = 0; + this.anchor = GridBagConstraints.CENTER; + this.fill = 0; + this.insets = new Insets(0, 0, 0, 0); + this.ipadx = 0; + this.ipady = 0; + return this; + } + + public GBC copy() { + GBC c2 = new GBC(); + c2.gridx = this.gridx; + c2.gridy = this.gridy; + c2.gridwidth = this.gridwidth; + c2.gridheight = this.gridheight; + c2.weightx = this.weightx; + c2.weighty = this.weighty; + c2.anchor = this.anchor; + c2.fill = this.fill; + c2.insets = copyInsets(this.insets); + c2.ipadx = this.ipadx; + c2.ipady = this.ipady; + return c2; + } + + public GBC set(GridBagConstraints b) { + if (b != null) { + this.gridx = b.gridx; + this.gridy = b.gridy; + this.gridwidth = b.gridwidth; + this.gridheight = b.gridheight; + this.weightx = b.weightx; + this.weighty = b.weighty; + this.anchor = b.anchor; + this.fill = b.fill; + this.insets = copyInsets(b.insets); + this.ipadx = b.ipadx; + this.ipady = b.ipady; + } + return this; + } + + private Insets copyInsets(Insets o) { + if (o == null) { + return new Insets(0, 0, 0, 0); + } + return (Insets) o.clone(); + } } diff --git a/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test01_CreateTest.java b/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test01_CreateTest.java index ae26fc4c1..d2bc6fbc5 100755 --- a/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test01_CreateTest.java +++ b/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test01_CreateTest.java @@ -41,6 +41,8 @@ public class Test01_CreateTest { @Test public void minimal1() { + long a=System.currentTimeMillis(); + String wsPath = TestUtils.getTestBaseFolder().getPath(); NSession session = TestUtils.openNewTestWorkspace("--workspace", wsPath, @@ -83,6 +85,8 @@ public void minimal1() { NText txt = NTexts.of(session).parse(str); TestUtils.println("-----------------------"); TestUtils.println(txt); + long b=System.currentTimeMillis(); + System.out.println(b-a); } @Test @@ -157,7 +161,15 @@ public void default3() throws Exception { "--exploded", "--archetype", "minimal", "--verbose", - "--install-companions=false"); + "--install-companions=false" + ); + } + @Test + public void default4() throws Exception { + TestUtils.openNewTestWorkspace( + "--verbose" + ,"--install-companions=false" + ); } @Test diff --git a/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test29_DependencyTest.java b/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test29_DependencyTest.java index 2ec1bf1e9..9350ffc3b 100755 --- a/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test29_DependencyTest.java +++ b/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test29_DependencyTest.java @@ -8,10 +8,15 @@ import net.thevpc.nuts.*; import net.thevpc.nuts.boot.DefaultNBootOptionsBuilder; import net.thevpc.nuts.core.test.utils.TestUtils; +import net.thevpc.nuts.util.NOptional; +import net.thevpc.nuts.util.NStringMapFormat; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import java.util.List; +import java.util.Map; + /** * * @author thevpc @@ -27,6 +32,10 @@ public static void init() { @Test public void testSearchDescriptor() { +// NStringMapFormat f = NStringMapFormat.of("=", "&", "\\", false); +// NOptional>> u = f.parseDuplicates("b\\=c"); +// NOptional>> u = f.parseDuplicates("d=a,b\\=c"); +// NOptional>> u = f.parseDuplicates("cond-properties=a,b\\=c&exclusions=asm:asm,asm:asm-tree,log4j:log4j,oro:oro&profile=coverage"); String t1="net.sourceforge.cobertura:cobertura#${cobertura.version}?cond-properties=a,b\\=c&exclusions=asm:asm,asm:asm-tree,log4j:log4j,oro:oro&profile=coverage"; String t2="net.sourceforge.cobertura:cobertura#${cobertura.version}?cond-properties='a,b=c'&exclusions=asm:asm,asm:asm-tree,log4j:log4j,oro:oro&profile=coverage"; NDependency s = NDependency.of(t1).get(session); diff --git a/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test32_Id.java b/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test32_Id.java index 62a873f1b..8bc0554ca 100755 --- a/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test32_Id.java +++ b/test/nuts-runtime-test/src/test/java/net/thevpc/nuts/core/test/Test32_Id.java @@ -83,6 +83,6 @@ public void test06() { Map p = a.getProperties(); TestUtils.println(a.toString()); Assertions.assertEquals(1,p.size()); - Assertions.assertEquals("?a='?'",a.toString()); + Assertions.assertEquals("?a=?",a.toString()); } } diff --git a/third-party-companions/ndb/src/main/java/net/thevpc/nuts/toolbox/ndb/sql/derby/DerbyService.java b/third-party-companions/ndb/src/main/java/net/thevpc/nuts/toolbox/ndb/sql/derby/DerbyService.java index 15c2d570b..580705178 100644 --- a/third-party-companions/ndb/src/main/java/net/thevpc/nuts/toolbox/ndb/sql/derby/DerbyService.java +++ b/third-party-companions/ndb/src/main/java/net/thevpc/nuts/toolbox/ndb/sql/derby/DerbyService.java @@ -137,13 +137,10 @@ private Path download(String id, Path folder, boolean optional) { // Path downloadBaseFolder = folder//.resolve(iid.getVersion().getValue()); Path targetFile = folder.resolve(iid.getArtifactId() + ".jar"); if (!Files.exists(targetFile)) { - if (optional) { - Path r = NFetchCommand.of(id,session).setLocation(targetFile).setFailFast(false).getResultPath(); - if (r != null) { - LOG.with().session(session).level(Level.FINEST).verb(NLogVerb.READ).log(NMsg.ofJ("downloading {0} to {1}", id, targetFile)); - } - } else { - NFetchCommand.of(id,session).setLocation(targetFile).failFast().getResultPath(); + NPath targetPath=NPath.of(targetFile,session); + NPath r = NFetchCommand.of(id,session).setFailFast(!optional).getResultPath(); + if (r != null) { + r.copyTo(targetPath); LOG.with().session(session).level(Level.FINEST).verb(NLogVerb.READ).log(NMsg.ofJ("downloading {0} to {1}", id, targetFile)); } } else {