001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.commons.rdf.jsonldjava;
019
020import java.util.Locale;
021import java.util.Objects;
022import java.util.Optional;
023
024import org.apache.commons.rdf.api.IRI;
025import org.apache.commons.rdf.api.Literal;
026import org.apache.commons.rdf.simple.Types;
027
028import com.github.jsonldjava.core.RDFDataset.Node;
029
030public interface JsonLdLiteral extends JsonLdTerm, Literal {
031}
032
033class JsonLdLiteralImpl extends JsonLdTermImpl implements JsonLdLiteral {
034
035    JsonLdLiteralImpl(final Node node) {
036        super(node);
037        if (!node.isLiteral()) {
038            throw new IllegalArgumentException("Node is not a Literal:" + node);
039        }
040    }
041
042    private static String lowerCase(final String langTag) {
043        return langTag.toLowerCase(Locale.ROOT);
044    }
045
046    @Override
047    public String ntriplesString() {
048        final StringBuilder sb = new StringBuilder();
049        sb.append('"');
050        // Escape special characters
051        sb.append(getLexicalForm().replace("\\", "\\\\"). // escaped to \\
052                replace("\"", "\\\""). // escaped to \"
053                replace("\r", "\\r"). // escaped to \r
054                replace("\n", "\\n")); // escaped to \n
055        sb.append('"');
056
057        if (getLanguageTag().isPresent()) {
058            sb.append("@");
059            sb.append(getLanguageTag().get());
060        } else if (!getDatatype().equals(Types.XSD_STRING)) {
061            sb.append("^^");
062            sb.append(getDatatype().ntriplesString());
063        }
064        return sb.toString();
065    }
066
067    @Override
068    public String getLexicalForm() {
069        return node.getValue();
070    }
071
072    @Override
073    public IRI getDatatype() {
074        return new JsonLdIRIImpl(node.getDatatype());
075    }
076
077    @Override
078    public Optional<String> getLanguageTag() {
079        return Optional.ofNullable(node.getLanguage());
080    }
081
082    @Override
083    public int hashCode() {
084        return Objects.hash(node.getValue(), node.getDatatype(),
085                getLanguageTag().map(JsonLdLiteralImpl::lowerCase));
086    }
087
088    @Override
089    public boolean equals(final Object obj) {
090        // COMMONSRDF-56: Do **not** use
091        // asJsonLdNode().compareTo(other.asJsonLdNode())
092        if (obj instanceof Literal) {
093            final Literal other = (Literal) obj;
094            return getLexicalForm().equals(other.getLexicalForm())
095                    && getDatatype().equals(other.getDatatype())
096                    && getLanguageTag().map(JsonLdLiteralImpl::lowerCase)
097                        .equals(other.getLanguageTag().map(JsonLdLiteralImpl::lowerCase));
098        }
099        return false;
100    }
101}