
001/*- 002 * #%L 003 * HAPI FHIR Storage api 004 * %% 005 * Copyright (C) 2014 - 2025 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.patch; 021 022/** 023 * This class is deprecated; consider using ParsedFhirPath, which allows much greater flexibility 024 * in handling a fhirpath for various actions 025 * 026 * This class helps parse a FHIR path into its component parts for easier patch operation processing. 027 * It has 3 components: 028 * - The last element name, which is the last element in the path (not including any list index or filter) 029 * - The containing path, which is the prefix of the path up to the last element 030 * - A flag indicating whether the path has a filter or index on the last element of the path, which indicates 031 * that the path we are dealing is probably for a list element. 032 * Examples: 033 * 1. For path "Patient.identifier[2].system", 034 * - the lastElementName is "system", 035 * - the containingPath is "Patient.identifier[2]", 036 * - and endsWithAFilterOrIndex flag is false 037 * 038 * 2. For path "Patient.identifier[2]" or for path "Patient.identifier.where('system'='sys1')" 039 * - the lastElementName is "identifier", 040 * - the containingPath is "Patient", 041 * - and the endsWithAFilterOrIndex is true 042 */ 043@Deprecated() 044public class ParsedPath { 045 private final String myLastElementName; 046 private final String myContainingPath; 047 private final boolean myEndsWithAFilterOrIndex; 048 049 public ParsedPath(String theLastElementName, String theContainingPath, boolean theEndsWithAFilterOrIndex) { 050 myLastElementName = theLastElementName; 051 myContainingPath = theContainingPath; 052 myEndsWithAFilterOrIndex = theEndsWithAFilterOrIndex; 053 } 054 055 /** 056 * returns the last element of the path 057 */ 058 public String getLastElementName() { 059 return myLastElementName; 060 } 061 062 /** 063 * Returns the prefix of the path up to the last FHIR resource element 064 */ 065 public String getContainingPath() { 066 return myContainingPath; 067 } 068 069 /** 070 * Returns whether the path has a filter or index on the last element of the path, which indicates 071 * that the path we are dealing is probably a list element. 072 */ 073 public boolean getEndsWithAFilterOrIndex() { 074 return myEndsWithAFilterOrIndex; 075 } 076 077 public static ParsedPath parse(String path) { 078 String containingPath; 079 String elementName; 080 boolean endsWithAFilterOrIndex = false; 081 082 if (path.endsWith(")")) { 083 // This is probably a filter, so we're probably dealing with a list 084 endsWithAFilterOrIndex = true; 085 int filterArgsIndex = path.lastIndexOf('('); // Let's hope there aren't nested parentheses 086 int lastDotIndex = path.lastIndexOf( 087 '.', filterArgsIndex); // There might be a dot inside the parentheses, so look to the left of that 088 int secondLastDotIndex = path.lastIndexOf('.', lastDotIndex - 1); 089 containingPath = path.substring(0, secondLastDotIndex); 090 elementName = path.substring(secondLastDotIndex + 1, lastDotIndex); 091 } else if (path.endsWith("]")) { 092 // This is almost definitely a list 093 endsWithAFilterOrIndex = true; 094 int openBracketIndex = path.lastIndexOf('['); 095 int lastDotIndex = path.lastIndexOf('.', openBracketIndex); 096 containingPath = path.substring(0, lastDotIndex); 097 elementName = path.substring(lastDotIndex + 1, openBracketIndex); 098 } else { 099 int lastDot = path.lastIndexOf("."); 100 containingPath = path.substring(0, lastDot); 101 elementName = path.substring(lastDot + 1); 102 } 103 104 return new ParsedPath(elementName, containingPath, endsWithAFilterOrIndex); 105 } 106}