001/* ***** BEGIN LICENSE BLOCK ***** 002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 003 * 004 * The contents of this file are subject to the Mozilla Public License Version 005 * 1.1 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * http://www.mozilla.org/MPL/ 008 * 009 * Software distributed under the License is distributed on an "AS IS" basis, 010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 011 * for the specific language governing rights and limitations under the 012 * License. 013 * 014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in 015 * Java(TM), hosted at https://github.com/gunterze/dcm4che. 016 * 017 * The Initial Developer of the Original Code is 018 * Agfa Healthcare. 019 * Portions created by the Initial Developer are Copyright (C) 2011 020 * the Initial Developer. All Rights Reserved. 021 * 022 * Contributor(s): 023 * See @authors listed below 024 * 025 * Alternatively, the contents of this file may be used under the terms of 026 * either the GNU General Public License Version 2 or later (the "GPL"), or 027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 028 * in which case the provisions of the GPL or the LGPL are applicable instead 029 * of those above. If you wish to allow use of your version of this file only 030 * under the terms of either the GPL or the LGPL, and not to allow others to 031 * use your version of this file under the terms of the MPL, indicate your 032 * decision by deleting the provisions above and replace them with the notice 033 * and other provisions required by the GPL or the LGPL. If you do not delete 034 * the provisions above, a recipient may use your version of this file under 035 * the terms of any one of the MPL, the GPL or the LGPL. 036 * 037 * ***** END LICENSE BLOCK ***** */ 038 039package org.dcm4che3.data; 040 041import java.io.Serializable; 042import java.util.ArrayList; 043 044import org.dcm4che3.util.TagUtils; 045 046/** 047 * @author Gunter Zeilinger <gunterze@gmail.com> 048 */ 049public class ValueSelector implements Serializable { 050 051 private static final long serialVersionUID = 8346808223314626639L; 052 053 private static final ItemPointer[] NO_ITEMPOINTERS = {}; 054 private static final int MIN_ITEM_POINTER_STR_LEN = 43; 055 056 public final int tag; 057 public final String privateCreator; 058 public final VR vr; 059 public final int valueIndex; 060 public final ItemPointer[] itemPointers; 061 062 public ValueSelector(String privateCreator, int tag, VR vr, int index, 063 ItemPointer... itemPointers) { 064 this.tag = tag; 065 this.privateCreator = privateCreator; 066 this.vr = vr; 067 this.valueIndex = index; 068 this.itemPointers = itemPointers.clone(); 069 } 070 071 public String selectStringValue(Attributes attrs, String defVal) { 072 Attributes item = attrs.getNestedDataset(itemPointers); 073 return item != null ? item.getString(privateCreator, tag, vr, valueIndex, defVal) : defVal; 074 } 075 076 @Override 077 public String toString() { 078 StringBuilder sb = new StringBuilder(32); 079 for (ItemPointer ip : itemPointers) 080 appendTo(ip.sequenceTag, ip.privateCreator, ip.itemIndex, 081 "\"]/Item[@number=\"", "\"]/", sb); 082 appendTo(tag, privateCreator, valueIndex, 083 "\"]/Value[@number=\"", "\"]", sb); 084 return sb.toString(); 085 } 086 087 private void appendTo(int tag, String privateCreator, int index, String valueOrItem, 088 String suffix, StringBuilder sb) { 089 sb.append("DicomAttribute[@tag=\"").append(TagUtils.toHexString(tag)); 090 if (privateCreator != null) 091 sb.append("\" and @privateCreator=\"").append(privateCreator); 092 if (vr != null) 093 sb.append("\" and @vr=\"").append(vr); 094 sb.append(valueOrItem).append(index + 1).append(suffix); 095 } 096 097 public static ValueSelector valueOf(String s) { 098 int fromIndex = s.lastIndexOf("DicomAttribute"); 099 try { 100 return new ValueSelector( 101 selectPrivateCreator(s, fromIndex), 102 selectTag(s, fromIndex), 103 selectVR(s, fromIndex), 104 selectNumber(s, fromIndex) - 1, 105 itemPointersOf(s, fromIndex)); 106 } catch (Exception e) { 107 throw new IllegalArgumentException(s,e); 108 } 109 } 110 111 private static int selectTag(String s, int fromIndex) { 112 String tagStr = select("@tag=", s, fromIndex); 113 return Integer.parseInt(tagStr, 16); 114 } 115 116 private static String selectPrivateCreator(String s, int fromIndex) { 117 return select("@privateCreator=", s, fromIndex); 118 } 119 120 private static int selectNumber(String s, int fromIndex) { 121 String no = select("@number=", s, fromIndex); 122 return Integer.parseInt(no); 123 } 124 125 private static VR selectVR(String s, int fromIndex) { 126 String vrStr = select("@vr=", s, fromIndex); 127 return vrStr != null ? VR.valueOf(vrStr) : null; 128 } 129 130 private static ItemPointer[] itemPointersOf(String s, int endIndex) { 131 if (endIndex == 0) 132 return NO_ITEMPOINTERS; 133 134 ArrayList<ItemPointer> list = new ArrayList<ItemPointer>(); 135 int fromIndex = 0; 136 while (fromIndex < endIndex) { 137 list.add(new ItemPointer( 138 selectPrivateCreator(s, fromIndex), 139 selectTag(s, fromIndex), 140 selectNumber(s, fromIndex) - 1)); 141 fromIndex = s.indexOf("DicomAttribute", 142 fromIndex + MIN_ITEM_POINTER_STR_LEN); 143 } 144 return list.toArray(new ItemPointer[list.size()]); 145 } 146 147 private static String select(String key, String s, int fromIndex) { 148 int pos = s.indexOf(key, fromIndex); 149 if (pos < 0) 150 return null; 151 152 int quotePos = pos + key.length(); 153 int beginIndex = quotePos + 1; 154 return s.substring(beginIndex, s.indexOf(s.charAt(quotePos), beginIndex)); 155 } 156 157}