/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * 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: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.dicom.codec.utils; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.List; import org.weasis.core.api.media.data.MediaElement; import org.weasis.core.api.media.data.TagUtil; import org.weasis.core.api.media.data.TagW; import org.weasis.core.api.util.StringUtil; import org.weasis.dicom.codec.DicomMediaIO; import org.weasis.dicom.codec.TagD; import org.weasis.dicom.codec.TagD.Level; import org.weasis.dicom.codec.display.Modality; public class SplittingModalityRules { private final Modality modality; private final List<Rule> singleFrameTags; private final List<Rule> multiFrameTags; private final SplittingModalityRules extendRules; public SplittingModalityRules(Modality modality) { this(modality, null); } public SplittingModalityRules(Modality modality, SplittingModalityRules extendRules) { this.modality = modality; this.extendRules = extendRules; this.singleFrameTags = extendRules == null ? new ArrayList<>() : new ArrayList<>(extendRules.getSingleFrameRules()); this.multiFrameTags = extendRules == null ? new ArrayList<>() : new ArrayList<>(extendRules.getMultiFrameRules()); } public Modality getModality() { return modality; } public List<Rule> getSingleFrameRules() { return singleFrameTags; } public List<Rule> getMultiFrameRules() { return multiFrameTags; } public SplittingModalityRules getExtendRules() { return extendRules; } public void addSingleFrameTags(TagW tag, Condition condition) { if (tag != null) { singleFrameTags.add(new Rule(tag, condition)); DicomMediaIO.tagManager.addTag(tag, Level.INSTANCE); } } public void addMultiFrameTags(TagW tag, Condition condition) { if (tag != null) { multiFrameTags.add(new Rule(tag, condition)); DicomMediaIO.tagManager.addTag(tag, Level.FRAME); } } public void addSingleFrameTags(int tagID, Condition condition) { addSingleFrameTags(TagD.getNullable(tagID), condition); } public void addMultiFrameTags(int tagID, Condition condition) { addMultiFrameTags(TagD.getNullable(tagID), condition); } public static class Rule { protected final TagW tag; protected final Condition condition; public Rule(TagW tag, Condition condition) { this.tag = tag; this.condition = condition; } public TagW getTag() { return tag; } public Condition getCondition() { return condition; } public boolean isTagValueMatching(MediaElement seriesMedia, MediaElement newMedia) { Object val1 = seriesMedia.getTagValue(tag); Object val2 = newMedia.getTagValue(tag); if (TagUtil.isEquals(val1, val2)) { return true; } if (condition != null) { // When all conditions match then the tag values not matching any more (media goes into a new // sub-series) return !condition.match(newMedia); } return false; } } public abstract static class Condition { public enum Type { equals, notEquals, equalsIgnoreCase, notEqualsIgnoreCase, contains, notContains, containsIgnoreCase, notContainsIgnoreCase } protected boolean not; public final Condition not() { this.not = !not; return this; } public abstract boolean match(MediaElement media); public void addChild(Condition child) { throw new UnsupportedOperationException(); } public boolean isEmpty() { return false; } } abstract static class CompositeCondition extends Condition { protected final ArrayList<Condition> childs = new ArrayList<>(); @Override public void addChild(Condition child) { childs.add(child); } @Override public boolean isEmpty() { return childs.isEmpty(); } } public static class And extends CompositeCondition { @Override public boolean match(MediaElement media) { for (Condition child : childs) { if (!child.match(media)) { return not; } } return !not; } } public static class Or extends CompositeCondition { @Override public boolean match(MediaElement media) { for (Condition child : childs) { if (child.match(media)) { return !not; } } return not; } } public static class DefaultCondition extends Condition { final TagW tag; final Condition.Type type; final Object object; public DefaultCondition(TagW tag, Type type, String value) { this.tag = tag; this.type = type; this.object = readValue(value); } private Object readValue(String value) { if (!StringUtil.hasText(value)) { return null; } return tag.getValue(value); } @Override public boolean match(MediaElement media) { Object value = media.getTagValue(tag); if (Type.equals.equals(type)) { return TagUtil.isEquals(value, object); } else if (Type.notEquals.equals(type)) { return !TagUtil.isEquals(value, object); } else if (Type.equalsIgnoreCase.equals(type)) { return TagUtil.isEquals(value, object, true); } else if (Type.notEqualsIgnoreCase.equals(type)) { return !TagUtil.isEquals(value, object, true); } String str = null; if (object != null) { if (object.getClass().isArray() && Array.getLength(object) > 0) { str = Array.get(object, 0).toString(); } else { str = object.toString(); } } switch (type) { case contains: return TagUtil.isContaining(value, str, false); case notContains: return !TagUtil.isContaining(value, str, false); case containsIgnoreCase: return TagUtil.isContaining(value, str, true); case notContainsIgnoreCase: return !TagUtil.isContaining(value, str, true); default: break; } return false; } } }