/*
* 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.jena.riot.process.normalize;
import static org.apache.jena.atlas.lib.Chars.CH_DOT ;
import static org.apache.jena.atlas.lib.Chars.CH_MINUS ;
import static org.apache.jena.atlas.lib.Chars.CH_PLUS ;
import org.apache.jena.datatypes.RDFDatatype ;
import org.apache.jena.graph.Node ;
import org.apache.jena.graph.NodeFactory ;
class NormalizeValue2
{
// faster (??)
// faster - directly check for correct forms : leading zeros, signs.
// Place into char[], zap with -1 if unwanted, recollect, rebuild string.
// --- Unfinished
static char NonChar = (char)0 ;
static char CH_ZERO = '0' ;
private static void stripLeadingPlus(char[] chars)
{
if ( chars[0] == CH_PLUS )
chars[0] = NonChar ;
}
// Works on decimals and integers as "." is "just" a stopping character.
private static void stripLeadingZeros(char[] chars)
{
// Avoid sign, or zapped sign.
int idx = 0 ;
if ( chars[0] == CH_MINUS || chars[0] == NonChar )
idx = 1 ;
// BUT not all zeros.
while( idx < chars.length && chars[idx] == CH_ZERO )
{
chars[idx] = NonChar ;
idx ++ ;
}
// All leading zeros - put one back.
// what about "-.1"?
if ( idx == chars.length || chars[idx] == '.' )
chars[idx-1] = CH_ZERO ;
}
// Decimal specific.
private static void stripTrailingZeros(char[] chars)
{
// Find the . (if any)
int iDot = 0 ;
for ( ; iDot < chars.length ; iDot++ )
{
if ( chars[iDot] == CH_DOT )
break ;
}
if ( iDot == chars.length )
// No dot.
// ??
{}
int start = 0 ;
if ( chars[0] == CH_MINUS || chars[0] == NonChar )
start = 1 ;
int idx ;
for ( idx = chars.length-1 ; idx >= start ; idx-- )
{
if ( chars[idx] != CH_ZERO )
break ;
chars[idx] = NonChar ;
}
// Don't remove all trailing zeros if "123." or "000"
if ( idx == start || chars[idx] == '.' )
chars[idx-1] = CH_ZERO ;
}
// Rebuild a string but return null for "no change"
private static String rebuild(char[] chars)
{
// i is the read index, j the write index.
boolean modified = false ;
int j = 0 ;
for ( int i = 0 ; i < chars.length ; i++)
{
if ( chars[i] == NonChar )
{
modified = true ;
continue ;
}
if ( ! modified )
continue ;
chars[j] = chars[i] ;
j++ ;
}
if ( ! modified )
return null ;
return new String(chars,0,j) ;
}
// --- Working versions
static DatatypeHandler dtInteger = (Node node, String lexicalForm, RDFDatatype datatype) -> {
char[] chars = lexicalForm.toCharArray() ;
if ( chars.length == 0 )
// Illegal lexical form.
return node ;
stripLeadingPlus(chars) ;
stripLeadingZeros(chars) ;
String lex2 = rebuild(chars) ;
if ( lex2 == null )
return node ;
return NodeFactory.createLiteral(lex2, datatype) ;
} ;
static DatatypeHandler dtDecimal = (Node node, String lexicalForm, RDFDatatype datatype) -> {
// Need to force "0."
char[] chars = lexicalForm.toCharArray() ;
if ( chars.length == 0 )
// Illegal lexical form.
return node ;
stripLeadingPlus(chars) ;
stripLeadingZeros(chars) ;
stripTrailingZeros(chars) ;
String lex2 = rebuild(chars) ;
if ( lex2 == null )
return node ;
return NodeFactory.createLiteral(lex2, datatype) ;
} ;
}