blob: 72a6bd68f8c537247f23600db72fb9118c1fcbe7 [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2009, 2018 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.internal.yaml.core.model;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.collections.ImList;
import org.eclipse.statet.jcommons.text.core.TextRegion;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.core.ElementName;
import org.eclipse.statet.ltk.model.core.elements.IModelElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceStructElement;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnit;
import org.eclipse.statet.ltk.model.core.elements.ISourceUnitModelInfo;
import org.eclipse.statet.yaml.core.ast.YamlAstNode;
import org.eclipse.statet.yaml.core.model.IYamlSourceElement;
import org.eclipse.statet.yaml.core.model.YamlElementName;
import org.eclipse.statet.yaml.core.model.YamlModel;
public abstract class YamlSourceElement implements IYamlSourceElement {
private static final ImList<YamlSourceElement> NO_CHILDREN= ImCollections.emptyList();
static final List<? extends IYamlSourceElement> getChildren(
final List<? extends IYamlSourceElement> children, final IModelElement.Filter filter) {
if (filter == null) {
return children;
}
else {
final ArrayList<IYamlSourceElement> filtered= new ArrayList<>(children.size());
for (final IYamlSourceElement child : children) {
if (filter.include(child)) {
filtered.add(child);
}
}
return filtered;
}
}
static final boolean hasChildren(
final List<? extends IYamlSourceElement> children, final IModelElement.Filter filter) {
if (filter == null) {
return (!children.isEmpty());
}
else {
for (final IYamlSourceElement child : children) {
if (filter.include(child)) {
return true;
}
}
return false;
}
}
public abstract static class Container extends YamlSourceElement {
List<YamlSourceElement> children= NO_CHILDREN;
TextRegion nameRegion;
private final YamlAstNode astNode;
public Container(final YamlAstNode astNode) {
super();
this.astNode= astNode;
}
@Override
public TextRegion getNameSourceRange() {
return this.nameRegion;
}
@Override
public TextRegion getSourceRange() {
return this.astNode;
}
@Override
public boolean hasSourceChildren(final Filter filter) {
return hasChildren(this.children, filter);
}
@Override
public List<? extends IYamlSourceElement> getSourceChildren(final Filter filter) {
return getChildren(this.children, filter);
}
@Override
public abstract Container getModelParent();
@Override
public boolean hasModelChildren(final Filter filter) {
return hasChildren(this.children, filter);
}
@Override
public List<? extends IModelElement> getModelChildren(final Filter filter) {
return getChildren(this.children, filter);
}
@Override
@SuppressWarnings("unchecked")
public <T> T getAdapter(final Class<T> adapterType) {
if (adapterType == AstNode.class) {
return (T) this.astNode;
}
return super.getAdapter(adapterType);
}
}
public static class SourceContainer extends Container {
private final ISourceUnit sourceUnit;
public SourceContainer(final ISourceUnit su, final YamlAstNode astNode) {
super(astNode);
this.sourceUnit= su;
}
@Override
public int getElementType() {
return IModelElement.C2_SOURCE_FILE;
}
@Override
public String getId() {
return this.sourceUnit.getId();
}
@Override
public YamlElementName getElementName() {
final ElementName elementName= this.sourceUnit.getElementName();
if (elementName instanceof YamlElementName) {
return (YamlElementName) elementName;
}
return YamlElementName.create(YamlElementName.RESOURCE, elementName.getSegmentName());
}
@Override
public ISourceUnit getSourceUnit() {
return this.sourceUnit;
}
@Override
public boolean exists() {
final ISourceUnitModelInfo modelInfo= getSourceUnit().getModelInfo(YamlModel.YAML_TYPE_ID, 0, null);
return (modelInfo != null && modelInfo.getSourceElement() == this);
}
@Override
public boolean isReadOnly() {
return this.sourceUnit.isReadOnly();
}
@Override
public ISourceStructElement getSourceParent() {
return null;
}
@Override
public Container getModelParent() {
return null;
}
}
public static class StructContainer extends Container {
private final int type;
private final Container parent;
public StructContainer(final int type, final Container parent, final YamlAstNode astNode) {
super(astNode);
this.type= type;
this.parent= parent;
}
@Override
public final int getElementType() {
return this.type;
}
@Override
public ISourceUnit getSourceUnit() {
return this.parent.getSourceUnit();
}
@Override
public boolean exists() {
return this.parent.exists();
}
@Override
public boolean isReadOnly() {
return this.parent.isReadOnly();
}
@Override
public ISourceStructElement getSourceParent() {
return this.parent;
}
@Override
public Container getModelParent() {
return this.parent;
}
}
protected YamlElementName name;
protected int occurrenceCount;
protected YamlSourceElement() {
}
@Override
public final String getModelTypeId() {
return YamlModel.YAML_TYPE_ID;
}
@Override
public String getId() {
final String name= getElementName().getDisplayName();
final StringBuilder sb= new StringBuilder(name.length() + 16);
sb.append(Integer.toHexString(getElementType() & MASK_C2));
sb.append(':');
sb.append(name);
sb.append('#');
sb.append(this.occurrenceCount);
return sb.toString();
}
@Override
public ElementName getElementName() {
return this.name;
}
@Override
public TextRegion getDocumentationRange() {
return null;
}
@Override
public <T> T getAdapter(final Class<T> adapterType) {
return null;
}
@Override
public int hashCode() {
return (getElementType() & MASK_C2) * getElementName().hashCode() + this.occurrenceCount;
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof YamlSourceElement)) {
return false;
}
final YamlSourceElement other= (YamlSourceElement) obj;
return ( (getElementType() & MASK_C2) == (getElementType() & MASK_C2))
&& (this.occurrenceCount == other.occurrenceCount)
&& ( ((getElementType() & MASK_C1) == C1_SOURCE) || (getSourceParent().equals(other.getSourceParent())) )
&& (getElementName().equals(other.getElementName()) );
}
}