/******************************************************************************* * Copyright (c) 2015 IBH SYSTEMS GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBH SYSTEMS GmbH - initial API and implementation *******************************************************************************/ package org.eclipse.packagedrone.repo.channel; import static java.util.Collections.emptyMap; import static java.util.Collections.unmodifiableList; import static java.util.Collections.unmodifiableMap; import static java.util.Collections.unmodifiableSet; import static java.util.Comparator.comparing; import static java.util.Comparator.nullsFirst; import java.time.Instant; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import org.eclipse.packagedrone.repo.MetaKey; import org.eclipse.packagedrone.repo.MetaKeys; public class ArtifactInformation implements Comparable<ArtifactInformation>, Validated { public static final Comparator<ArtifactInformation> NAME_COMPARATOR = nullsFirst ( comparing ( ArtifactInformation::getName ) ); private final String id; private final String parentId; // original copy-on-write instance used for the manipulator to use copy-on-write private final Set<String> modChildIds; private final Set<String> childIds; private final String name; private final long size; private final Instant creationTimestamp; // original copy-on-write instance used for the manipulator to use copy-on-write private final Set<String> modFacets; private final Set<String> facets; // original copy-on-write instance used for the manipulator to use copy-on-write private final List<ValidationMessage> modMessages; private final List<ValidationMessage> messages; private final Map<MetaKey, String> providedMetaData; private final Map<MetaKey, String> extractedMetaData; private final Map<MetaKey, String> metaData; private final String virtualizerAspectId; public ArtifactInformation ( final String id, final String parentId, final Set<String> childIds, final String name, final long size, final Instant creationTimestamp, final Set<String> facets, final List<ValidationMessage> messages, final Map<MetaKey, String> providedMetaData, final Map<MetaKey, String> extractedMetaData, final String virtualizerAspectId ) { this.id = id; this.parentId = parentId; if ( childIds != null ) { this.modChildIds = new CopyOnWriteArraySet<> ( childIds ); this.childIds = unmodifiableSet ( this.modChildIds ); } else { this.childIds = this.modChildIds = Collections.emptySet (); } this.name = name; this.size = size; this.creationTimestamp = creationTimestamp; this.modFacets = new CopyOnWriteArraySet<> ( facets ); this.facets = unmodifiableSet ( this.modFacets ); this.modMessages = new CopyOnWriteArrayList<> ( messages ); this.messages = unmodifiableList ( this.modMessages ); this.providedMetaData = providedMetaData != null ? unmodifiableMap ( new HashMap<> ( providedMetaData ) ) : emptyMap (); this.extractedMetaData = extractedMetaData != null ? unmodifiableMap ( new HashMap<> ( extractedMetaData ) ) : emptyMap (); this.metaData = MetaKeys.union ( providedMetaData, extractedMetaData ); this.virtualizerAspectId = virtualizerAspectId; } protected ArtifactInformation ( final ArtifactInformation other ) { this.id = other.id; this.parentId = other.parentId; this.childIds = other.childIds; this.modChildIds = other.modChildIds; this.name = other.name; this.size = other.size; this.creationTimestamp = other.creationTimestamp; this.facets = other.facets; this.modFacets = other.modFacets; this.messages = other.messages; this.modMessages = other.modMessages; this.providedMetaData = other.providedMetaData; this.extractedMetaData = other.extractedMetaData; this.metaData = other.metaData; this.virtualizerAspectId = other.virtualizerAspectId; } public boolean is ( final String type ) { return this.facets.contains ( type ); } public Set<String> getFacets () { return this.facets; } public String getId () { return this.id; } public String getParentId () { return this.parentId; } public Set<String> getChildIds () { return this.childIds; } public String getName () { return this.name; } public long getSize () { return this.size; } public Instant getCreationInstant () { return this.creationTimestamp; } public Date getCreationTimestamp () { return new Date ( this.creationTimestamp.toEpochMilli () ); } public Map<MetaKey, String> getMetaData () { return this.metaData; } public Map<MetaKey, String> getExtractedMetaData () { return this.extractedMetaData; } public Map<MetaKey, String> getProvidedMetaData () { return this.providedMetaData; } public String getVirtualizerAspectId () { return this.virtualizerAspectId; } @Override public int hashCode () { final int prime = 31; int result = 1; result = prime * result + ( this.id == null ? 0 : this.id.hashCode () ); return result; } @Override public boolean equals ( final Object obj ) { if ( this == obj ) { return true; } if ( obj == null ) { return false; } if ( ! ( obj instanceof ArtifactInformation ) ) { return false; } final ArtifactInformation other = (ArtifactInformation)obj; if ( this.id == null ) { if ( other.id != null ) { return false; } } else if ( !this.id.equals ( other.id ) ) { return false; } return true; } @Override public int compareTo ( final ArtifactInformation o ) { return this.id.compareTo ( o.id ); } @Override public Collection<ValidationMessage> getValidationMessages () { return this.messages; } @Override public String toString () { return String.format ( "[%s = %s]", this.id, this.name ); } public Manipulator createManipulator () { return new Manipulator ( this ); } public static class Manipulator { private final ArtifactInformation original; private Set<String> childIds; private Map<MetaKey, String> providedMetaData; private Map<MetaKey, String> extractedMetaData; private List<ValidationMessage> validationMessages; public Manipulator ( final ArtifactInformation original ) { this.original = original; /* although this is a modifiable version, we _must not_ change the list content! * Since it is the base of an immutable object. But if we have access to the original * CopyOnWriteArraySet, the copy constructor can make use of the copy on write variant */ this.childIds = new CopyOnWriteArraySet<> ( original.modChildIds ); this.providedMetaData = new HashMap<> ( original.providedMetaData ); this.extractedMetaData = new HashMap<> ( original.extractedMetaData ); this.validationMessages = new CopyOnWriteArrayList<> ( original.modMessages ); } public void setChildIds ( final Set<String> childIds ) { this.childIds = childIds; } public Set<String> getChildIds () { return this.childIds; } public ArtifactInformation build () { return new ArtifactInformation ( this.original.id, this.original.parentId, this.childIds, this.original.name, this.original.size, this.original.creationTimestamp, this.original.modFacets, this.validationMessages, this.providedMetaData, this.extractedMetaData, this.original.virtualizerAspectId ); } public Map<MetaKey, String> getProvidedMetaData () { return this.providedMetaData; } public void setProvidedMetaData ( final Map<MetaKey, String> providedMetaData ) { this.providedMetaData = providedMetaData; } public Map<MetaKey, String> getExtractedMetaData () { return this.extractedMetaData; } public void setExtractedMetaData ( final Map<MetaKey, String> extractedMetaData ) { this.extractedMetaData = extractedMetaData; } public void setValidationMessages ( final List<ValidationMessage> validationMessages ) { this.validationMessages = validationMessages; } } }