001/* 002 * Portions of this software was developed by employees of the National Institute 003 * of Standards and Technology (NIST), an agency of the Federal Government and is 004 * being made available as a public service. Pursuant to title 17 United States 005 * Code Section 105, works of NIST employees are not subject to copyright 006 * protection in the United States. This software may be subject to foreign 007 * copyright. Permission in the United States and in foreign countries, to the 008 * extent that NIST may hold copyright, to use, copy, modify, create derivative 009 * works, and distribute this software and its documentation without fee is hereby 010 * granted on a non-exclusive basis, provided that this notice and disclaimer 011 * of warranty appears in all copies. 012 * 013 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER 014 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY 015 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF 016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM 017 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE 018 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 019 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, 020 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, 021 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, 022 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR 023 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT 024 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. 025 */ 026 027package gov.nist.secauto.metaschema.core.metapath.function.library; 028 029import gov.nist.secauto.metaschema.core.metapath.DynamicContext; 030import gov.nist.secauto.metaschema.core.metapath.ISequence; 031import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; 032import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils; 033import gov.nist.secauto.metaschema.core.metapath.function.IArgument; 034import gov.nist.secauto.metaschema.core.metapath.function.IFunction; 035import gov.nist.secauto.metaschema.core.metapath.item.IItem; 036import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyUriItem; 037import gov.nist.secauto.metaschema.core.metapath.item.node.IDocumentNodeItem; 038import gov.nist.secauto.metaschema.core.metapath.item.node.INodeItem; 039import gov.nist.secauto.metaschema.core.util.ObjectUtils; 040 041import java.net.URI; 042import java.util.List; 043 044import edu.umd.cs.findbugs.annotations.NonNull; 045import edu.umd.cs.findbugs.annotations.Nullable; 046 047public final class FnDocumentUri { 048 049 @NonNull 050 static final IFunction SIGNATURE_NO_ARG = IFunction.builder() 051 .name("document-uri") 052 .namespace(MetapathConstants.NS_XPATH_FUNCTIONS) 053 .deterministic() 054 .contextDependent() 055 .focusDependent() 056 .returnType(IAnyUriItem.class) 057 .returnOne() 058 .functionHandler(FnDocumentUri::executeNoArg) 059 .build(); 060 061 @NonNull 062 static final IFunction SIGNATURE_ONE_ARG = IFunction.builder() 063 .name("document-uri") 064 .namespace(MetapathConstants.NS_XPATH_FUNCTIONS) 065 .deterministic() 066 .contextIndependent() 067 .focusIndependent() 068 .argument(IArgument.newBuilder() 069 .name("arg1") 070 .type(IDocumentNodeItem.class) 071 .zeroOrOne() 072 .build()) 073 .returnType(IAnyUriItem.class) 074 .returnOne() 075 .functionHandler(FnDocumentUri::executeOneArg) 076 .build(); 077 078 private FnDocumentUri() { 079 // disable construction 080 } 081 082 @SuppressWarnings("unused") 083 @NonNull 084 private static ISequence<IAnyUriItem> executeNoArg(@NonNull IFunction function, 085 @NonNull List<ISequence<?>> arguments, 086 @NonNull DynamicContext dynamicContext, 087 IItem focus) { 088 089 INodeItem item = FunctionUtils.requireTypeOrNull(INodeItem.class, focus); 090 091 ISequence<IAnyUriItem> retval; 092 if (item instanceof IDocumentNodeItem) { 093 IAnyUriItem uri = fnDocumentUri((IDocumentNodeItem) item); 094 retval = ISequence.of(uri); 095 } else { 096 retval = ISequence.empty(); 097 } 098 return retval; 099 } 100 101 @SuppressWarnings("unused") 102 @NonNull 103 private static ISequence<IAnyUriItem> executeOneArg(@NonNull IFunction function, 104 @NonNull List<ISequence<?>> arguments, 105 @NonNull DynamicContext dynamicContext, 106 IItem focus) { 107 108 ISequence<? extends INodeItem> arg = FunctionUtils.asType(ObjectUtils.requireNonNull(arguments.get(0))); 109 110 INodeItem item = FunctionUtils.getFirstItem(arg, true); 111 112 ISequence<IAnyUriItem> retval; 113 if (item == null) { 114 retval = ISequence.empty(); 115 } else if (item instanceof IDocumentNodeItem) { 116 IAnyUriItem uri = fnDocumentUri((IDocumentNodeItem) item); 117 retval = ISequence.of(uri); 118 } else { 119 retval = ISequence.empty(); 120 } 121 return retval; 122 } 123 124 /** 125 * Get the URI of the document. 126 * <p> 127 * Based on the XPath 3.1 <a href= 128 * "https://www.w3.org/TR/xpath-functions-31/#func-document-uri">fn:document-uri</a> 129 * function. 130 * 131 * @param document 132 * the document to get the URI for 133 * @return the URI of the document or {@code null} if not available 134 */ 135 @Nullable 136 public static IAnyUriItem fnDocumentUri(@NonNull IDocumentNodeItem document) { 137 URI documentUri = document.getDocumentUri(); 138 return documentUri == null ? null : IAnyUriItem.valueOf(documentUri); 139 } 140}