/** * OrbisGIS is a java GIS application dedicated to research in GIScience. * OrbisGIS is developed by the GIS group of the DECIDE team of the * Lab-STICC CNRS laboratory, see <http://www.lab-sticc.fr/>. * * The GIS group of the DECIDE team is located at : * * Laboratoire Lab-STICC – CNRS UMR 6285 * Equipe DECIDE * UNIVERSITÉ DE BRETAGNE-SUD * Institut Universitaire de Technologie de Vannes * 8, Rue Montaigne - BP 561 56017 Vannes Cedex * * OrbisGIS is distributed under GPL 3 license. * * Copyright (C) 2007-2014 CNRS (IRSTV FR CNRS 2488) * Copyright (C) 2015-2017 CNRS (Lab-STICC UMR CNRS 6285) * * This file is part of OrbisGIS. * * OrbisGIS is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * OrbisGIS is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * OrbisGIS. If not, see <http://www.gnu.org/licenses/>. * * For more information, please consult: <http://www.orbisgis.org/> * or contact directly: * info_at_ orbisgis.org */ package org.orbisgis.sqlconsole.codereformat; import java.util.ArrayList; import java.util.List; /* * Copyright (C) 2003 Gerd Wagner * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ public class CodeReformatorKernel { private CommentSpec[] _commentSpecs; private PieceMarkerSpec[] _pieceSpecs; private StateOfPosition[] _statesOfPosition; public CodeReformatorKernel(PieceMarkerSpec[] pieceSpecs, CommentSpec[] commentSpecs) { _commentSpecs = commentSpecs; _pieceSpecs = pieceSpecs; } public String[] toPieces(String in) { _statesOfPosition = getStatesOfPosition(in); List<String> ret = new ArrayList<String>(); // toUpperCase replaces the German ß by ss. // This will kill reformating later. // Since upperIn is just for building pieces // it is OK to place ß here. String upperIn = in.replaceAll("ß", "s"); upperIn = upperIn.toUpperCase(); int begin = 0; while(begin < in.length()) { Piece p = getNextToplevelPiece(begin, upperIn); if(null == p.spec) { ret.add(in.substring(begin).trim()); begin = in.length(); } else { int type = p.spec.getType(); switch(type) { case PieceMarkerSpec.TYPE_PIECE_MARKER_AT_BEGIN: if(begin < p.beginsAt && 0 < in.substring(begin, p.beginsAt).trim().length()) { ret.add(in.substring(begin, p.beginsAt).trim()); } int afterPieceMarker = p.beginsAt + p.spec.getLengthRightSpaced(); Piece nextP = getNextToplevelPiece(afterPieceMarker, upperIn); if(null == nextP.spec) { ret.add( in.substring(p.beginsAt).trim() ); begin = in.length(); } else { if(PieceMarkerSpec.TYPE_PIECE_MARKER_AT_END == nextP.spec.getType()) { if(nextP.beginsAt + nextP.spec.getLengthRightSpaced() < in.length()) { ret.add( in.substring(p.beginsAt, nextP.beginsAt + nextP.spec.getLengthRightSpaced()).trim() ); } else { ret.add( in.substring(p.beginsAt).trim() ); } begin = nextP.beginsAt + nextP.spec.getLengthRightSpaced(); } else { ret.add( in.substring(p.beginsAt, nextP.beginsAt).trim() ); begin = nextP.beginsAt; } } break; case PieceMarkerSpec.TYPE_PIECE_MARKER_AT_END: if(p.beginsAt + p.spec.getLengthRightSpaced() < in.length()) { ret.add( in.substring(begin, p.beginsAt + p.spec.getLengthRightSpaced() ).trim() ); } else { ret.add( in.substring(begin).trim() ); } begin = p.beginsAt + p.spec.getLengthRightSpaced(); break; case PieceMarkerSpec.TYPE_PIECE_MARKER_IN_OWN_PIECE: if(begin < p.beginsAt && 0 < in.substring(begin, p.beginsAt).trim().length()) { ret.add(in.substring(begin, p.beginsAt).trim()); } if(p.beginsAt + p.spec.getLengthRightSpaced() < in.length()) { ret.add( in.substring(p.beginsAt, p.beginsAt + p.spec.getLengthRightSpaced() ).trim() ); } else { ret.add( in.substring(p.beginsAt).trim() ); } begin = p.beginsAt + p.spec.getLengthRightSpaced(); break; } } } return ret.toArray(new String[ret.size()]); } private Piece getNextToplevelPiece(int startAt, String in) { Piece ret = new Piece(); ret.beginsAt = in.length(); for(int i=0; i < _pieceSpecs.length; ++i) { int buf = getTopLevelIndex(startAt, in, _pieceSpecs[i]); if(-1 < buf && buf < ret.beginsAt) { ret.spec = _pieceSpecs[i]; ret.beginsAt = buf; } } if(null == ret.spec) { ret.beginsAt = startAt; } return ret; } private int getTopLevelIndex(int startAt, String in, PieceMarkerSpec pieceSpec) { int ix = in.indexOf(pieceSpec.getPieceMarker(), startAt); while(-1 != ix) { if(_statesOfPosition[ix].isTopLevel) { if(pieceSpec.needsSuroundingWhiteSpaces()) { char before = (0 == ix ? ' ': in.charAt(ix-1) ); int pieceMArkerEnd = ix + pieceSpec.getPieceMarker().length() - 1; char after = (pieceMArkerEnd == in.length() - 1 ? ' ': in.charAt(pieceMArkerEnd+1) ); if(Character.isWhitespace(before) && Character.isWhitespace(after)) { return ix; } } else { return ix; } } ix = in.indexOf(pieceSpec.getPieceMarker(), ix + 1); } return -1; } public StateOfPosition[] getStatesOfPosition(String in) { StateOfPosition[] ret = new StateOfPosition[in.length()]; StateOfPosition buf = new StateOfPosition(); for(int i=0; i < in.length(); ++i) { if('\'' == in.charAt(i)) { ++buf.literalSepCount; } if(0 == buf.literalSepCount % 2) { for(int j=0; j < _commentSpecs.length; ++j) { if(in.substring(i).startsWith(_commentSpecs[j].commentBegin)) { if(-1 == buf.commentIndex) { buf.commentIndex = j; } } if(in.substring(i).startsWith(_commentSpecs[j].commentEnd)) { if(j == buf.commentIndex) { buf.commentIndex = -1; } } } } if(0 == buf.literalSepCount % 2 && -1 == buf.commentIndex) { if('(' == in.charAt(i)) { ++buf.braketDepth; } if(')' == in.charAt(i)) { --buf.braketDepth; } } if( -1 == buf.commentIndex && 0 == buf.literalSepCount % 2 && 0 == buf.braketDepth ) { buf.isTopLevel = true; } else { buf.isTopLevel = false; } ret[i] = (StateOfPosition)buf.clone(); } return ret; } }