blob: a6f5836a39cb18b14e8ffb109babaf0927626404 [file] [log] [blame]
/*
* 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.sling.ide.eclipse.ui.nav.model;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.sling.ide.eclipse.core.internal.Activator;
import org.apache.sling.ide.serialization.SerializationManager;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.xml.sax.SAXException;
import de.pdark.decentxml.Document;
import de.pdark.decentxml.Element;
import de.pdark.decentxml.XMLTokenizer.Type;
/** WIP: model object for a [.content.xml] shown in the content package view in project explorer **/
public class GenericJcrRootFile extends JcrNode {
final IFile file;
private final Document document;
public GenericJcrRootFile(JcrNode parent, final IFile file) throws ParserConfigurationException, SAXException, IOException, CoreException {
if (file==null) {
throw new IllegalArgumentException("file must not be null");
}
this.file = file;
setResource(file);
if (parent==null) {
throw new IllegalArgumentException("parent must not be null");
}
this.parent = parent;
this.domElement = null;
try (InputStream in = file.getContents()) {
this.document = TolerantXMLParser.parse(in, file.getFullPath().toOSString());
handleJcrRoot(this.document.getRootElement());
}
}
@Override
public int hashCode() {
return file.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof GenericJcrRootFile) {
GenericJcrRootFile other = (GenericJcrRootFile) obj;
return file.equals(other.file);
}
return false;
}
private void handleJcrRoot(Element element) {
List<Element> children = element.getChildren();
final JcrNode effectiveParent;
if (isRootContentXml()) {
if (parent instanceof DirNode) {
DirNode dirNodeParent = (DirNode)parent;
JcrNode effectiveSibling = dirNodeParent.getEffectiveSibling();
if (effectiveSibling!=null) {
effectiveSibling.dirSibling = dirNodeParent;
handleProperties(element, effectiveSibling.properties);
} else {
handleProperties(element, parent.properties);
}
effectiveParent = parent;
} else {
handleProperties(element, parent.properties);
effectiveParent = parent;
}
} else {
handleProperties(element, properties);
effectiveParent = this;
parent.addChild(this);
}
for (Iterator<Element> it = children.iterator(); it.hasNext();) {
Element aChild = it.next();
handleChild(effectiveParent, aChild);
}
}
private boolean isRootContentXml() {
return file.getName().equals(".content.xml");
}
private void handleProperties(Element domNode, ModifiableProperties properties) {
properties.setNode(this, domNode);
// NamedNodeMap attributes = domNode.getAttributes();
// for(int i=0; i<attributes.getLength(); i++) {
// Node attr = attributes.item(i);
// properties.add(attr.getNodeName(), attr.getNodeValue());
// }
}
@Override
public String getLabel() {
if (isRootContentXml()) {
return "SHOULD NOT OCCUR";
} else {
// de-escape the file name
String label = file.getName();
// 1. remove the trailing .xml
if (label.endsWith(".xml")) {
label = label.substring(0, label.length()-4);
}
// 2. de-escape stuff like '_cq_' to 'cq:'
if (label.startsWith("_")) {
label = label.substring(1);
int first = label.indexOf("_");
if (first!=-1) {
label = label.substring(0, first) + ":" + label.substring(first+1);
}
}
return label;
}
}
private void handleChild(JcrNode parent, Element domNode) {
if (domNode.getType() == Type.TEXT) {
// ignore
return;
}
JcrNode childJcrNode = new JcrNode(parent, domNode, this, null);
handleProperties(domNode, childJcrNode.properties);
for (Element element : domNode.getChildren()) {
handleChild(childJcrNode, element);
}
}
public void pickResources(List<IResource> membersList) {
final SerializationManager serializationManager = Activator.getDefault().getSerializationManager();
for (Iterator<IResource> it = membersList.iterator(); it.hasNext();) {
final IResource resource = it.next();
final String resName = resource.getName();
Iterator<JcrNode> it2;
if (isRootContentXml()) {
it2 = parent.children.iterator();
} else {
it2 = children.iterator();
}
while(it2.hasNext()) {
JcrNode aChild = it2.next();
if (resName.equals(serializationManager.getOsPath(aChild.getName()))) {
// then pick this one
it.remove();
aChild.setResource(resource);
break;
}
}
}
}
@Override
public IFile getFileForEditor() {
return file;
}
@Override
void createDomChild(String childNodeName, String childNodeType) {
createChild(childNodeName, childNodeType, document.getRootElement(), underlying);
}
public void save() {
try {
String xml = document.toXML();
file.setContents(new ByteArrayInputStream(xml.getBytes()), true, true, new NullProgressMonitor());
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SyncDirManager.syncDirChanged(getSyncDir());
}
@Override
public boolean canBeRenamed() {
return true;
}
@Override
public boolean canBeDeleted() {
return true;
}
@Override
public void rename(String string) {
try {
file.move(file.getParent().getFullPath().append(string+".xml"), true, new NullProgressMonitor());
} catch (CoreException e) {
Activator.getDefault().getPluginLogger().error("Error renaming resource ("+file+"): "+e, e);
}
}
@Override
public void delete() {
try {
file.delete(true, new NullProgressMonitor());
} catch (CoreException e) {
Activator.getDefault().getPluginLogger().error("Error deleting resource ("+file+"): "+e, e);
}
}
}