blob: a82e20fec975b66bb23ea402db70a877a9784955 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
* Angelo Zerr <angelo.zerr@gmail.com> - copied from org.eclipse.wst.css.core.internal.formatter.JSONFormatUtil
* modified in order to process JSON Objects.
*******************************************************************************/
package org.eclipse.wst.json.core.internal.format;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.wst.json.core.document.IJSONModel;
import org.eclipse.wst.json.core.document.IJSONNode;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.w3c.dom.Node;
public class JSONFormatUtil {
public List collectJSONNodes(IStructuredModel model, int start, int length) {
List nodes = new ArrayList();
IndexedRegion startNode = model.getIndexedRegion(start);
IndexedRegion endNode = model.getIndexedRegion(start + length - 1);
if (startNode == null || endNode == null) {
return nodes;
}
if (model instanceof IJSONModel && startNode instanceof IJSONNode
&& endNode instanceof IJSONNode) {
// JSON model
IJSONNode ca = getCommonAncestor((IJSONNode) startNode,
(IJSONNode) endNode);
if (ca != null) {
for (IJSONNode node = ca.getFirstChild(); node != null
&& start + length < ((IndexedRegion) node)
.getStartOffset(); node = node.getNextSibling()) {
if (start < ((IndexedRegion) node).getEndOffset()) {
nodes.add(node);
}
}
}
}
return nodes;
}
/**
* getCommonAncestor method
*
* @return org.w3c.dom.Node
* @param node
* org.w3c.dom.Node
*/
private Node getCommonAncestor(Node node1, Node node2) {
if (node1 == null || node2 == null)
return null;
for (Node na = node2; na != null; na = na.getParentNode()) {
for (Node ta = node1; ta != null; ta = ta.getParentNode()) {
if (ta == na)
return ta;
}
}
return null; // not found
}
private IJSONNode getCommonAncestor(IJSONNode nodeA, IJSONNode nodeB) {
if (nodeA == null || nodeB == null) {
return null;
}
for (IJSONNode na = nodeA; na != null; na = na.getParentNode()) {
for (IJSONNode ta = nodeB; ta != null; ta = ta.getParentNode()) {
if (ta == na) {
return ta;
}
}
}
return null; // not found
}
/**
*/
public void replaceSource(IStructuredModel model, int offset, int length,
String source) {
if (model == null)
return;
IStructuredDocument structuredDocument = model.getStructuredDocument();
if (structuredDocument == null)
return;
if (offset >= 0 && length >= 0
&& offset + length <= structuredDocument.getLength()) {
if (structuredDocument.containsReadOnly(offset, length))
return;
if (source == null)
source = new String();
// We use 'structuredDocument' as the requester object just so
// this and the other
// format-related 'repalceText' (in replaceSource) can use the
// same requester.
// Otherwise, if requester is not identical,
// the undo group gets "broken" into multiple pieces based
// on the requesters being different. Technically, any unique,
// common
// requester object would work.
structuredDocument.replaceText(structuredDocument, offset, length,
source);
}
}
public synchronized static JSONFormatUtil getInstance() {
if (fInstance == null) {
fInstance = new JSONFormatUtil();
}
return fInstance;
}
private JSONFormatUtil() {
super();
}
private static JSONFormatUtil fInstance;
}