| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.daffodil.processors.unparsers |
| |
| import org.apache.daffodil.exceptions.Assert |
| import org.apache.daffodil.processors.OutputNewLineEv |
| import org.apache.daffodil.processors.InfosetCachedEvaluatable |
| import org.apache.daffodil.processors.Evaluatable |
| import org.apache.daffodil.processors.ParseOrUnparseState |
| import org.apache.daffodil.util.Maybe |
| import org.apache.daffodil.cookers.EntityReplacer |
| import org.apache.daffodil.dsom.DPathCompileInfo |
| |
| class NilStringLiteralForUnparserEv( |
| tci: DPathCompileInfo, |
| maybeOutputNewLineEv: Maybe[OutputNewLineEv], |
| stringLiteralRaw: String) |
| extends Evaluatable[String](tci) |
| with InfosetCachedEvaluatable[String] { |
| |
| override lazy val runtimeDependencies = maybeOutputNewLineEv.toList |
| |
| override protected def compute(state: ParseOrUnparseState): String = { |
| val endMarker = "__daffodil_stringLiteralForUnparser_endMarker__" |
| Assert.invariant(!stringLiteralRaw.endsWith(endMarker)) |
| val rawWithEndMark = stringLiteralRaw + endMarker |
| EntityReplacer { er => |
| val cookedWithEndMark = er.replaceForUnparse(rawWithEndMark) |
| val chunksSeparatedByNL = cookedWithEndMark.split(er.markerForNL).toSeq |
| val last = chunksSeparatedByNL.last |
| val butLast = chunksSeparatedByNL.take(chunksSeparatedByNL.length - 1) |
| val chunks = |
| if (last == endMarker) { |
| // this means the original string ended with a %NL; |
| // because the endMarker is all by itself. |
| butLast :+ "" // replace it by an empty string |
| } else { |
| // the original string did not end with a %NL; |
| // so that means whatever the last token is, it has our endMarker |
| // glued onto it, and we must remove that. |
| Assert.invariant(last.endsWith(endMarker)) |
| butLast :+ last.replace(endMarker, "") |
| } |
| |
| if (chunks.length == 1) { |
| // there are no NL entities. There is only a single chunk. |
| chunks.head |
| } else { |
| tci.schemaDefinitionUnless( |
| maybeOutputNewLineEv.isDefined, |
| "Property dfdl:outputNewLine is required, but it is not defined.") |
| val nl = maybeOutputNewLineEv.get.evaluate(state) |
| val sl = chunks.mkString(nl) |
| sl |
| } |
| } |
| } |
| } |