001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: /* $Id:$ */
019: package org.apache.lenya.cms.jcr.usecases;
020:
021: import java.io.IOException;
022:
023: import javax.jcr.ImportUUIDBehavior;
024: import javax.jcr.Item;
025: import javax.jcr.LoginException;
026: import javax.jcr.Repository;
027: import javax.jcr.RepositoryException;
028: import javax.jcr.Session;
029: import javax.jcr.Workspace;
030:
031: import org.apache.avalon.framework.CascadingRuntimeException;
032: import org.apache.cocoon.components.ContextHelper;
033: import org.apache.cocoon.environment.Request;
034: import org.apache.cocoon.servlet.multipart.Part;
035: import org.apache.lenya.cms.usecase.AbstractUsecase;
036: import org.xml.sax.Attributes;
037: import org.xml.sax.InputSource;
038: import org.xml.sax.SAXException;
039: import org.xml.sax.XMLReader;
040: import org.xml.sax.helpers.DefaultHandler;
041: import org.xml.sax.helpers.XMLReaderFactory;
042:
043: /**
044: * Import JCR content.
045: */
046: public class JCRImport extends AbstractUsecase {
047:
048: private static final String IMPORT_TARGET_PARAM = "lenya.usecase.importExport.import";
049: private static final String IMPORT_TARGET_PUBLICATION = "publication";
050: private static final String IMPORT_TARGET_REPOSITORY = "repository";
051:
052: private static final String JCR_LENYA_ROOT = "/";
053: private static final String JCR_LENYA_BASE_NAME = "lenya";
054: private static final String JCR_LENYA_PUBLICATON_ROOT = "/lenya/pubs";
055:
056: /**
057: * @see org.apache.lenya.cms.usecase.AbstractUsecase#doExecute()
058: */
059: protected void doExecute() throws Exception {
060: Request request = ContextHelper.getRequest(this .context);
061:
062: Part jcrImport = (Part) request.get("jcrcontent");
063:
064: // Get name of first JCR node ('lenya' or publication name).
065: String firstNodeName;
066: try {
067: firstNodeName = getFirstNodeName(new InputSource(jcrImport
068: .getInputStream()));
069: } catch (Exception e) {
070: throw new JCRImportException(
071: "Error getting first node name of import data");
072: }
073: if (firstNodeName == null) {
074: throw new JCRImportException(
075: "Reading repository import data failed");
076: }
077:
078: Repository repo = null;
079: try {
080: repo = (Repository) manager.lookup(Repository.class
081: .getName());
082: } catch (Exception e) {
083: throw new CascadingRuntimeException(
084: "Cannot lookup repository", e);
085: }
086:
087: try {
088: Session session;
089: try {
090: session = repo.login();
091: } catch (LoginException e1) {
092: throw new JCRImportException(
093: "Login to repository failed", e1);
094: } catch (RepositoryException e1) {
095: throw new JCRImportException(
096: "Cannot access repository", e1);
097: }
098:
099: Workspace ws = session.getWorkspace();
100:
101: String importTarget = request
102: .getParameter(IMPORT_TARGET_PARAM);
103: if (IMPORT_TARGET_REPOSITORY.equals(importTarget)) {
104: // Import Lenya repository
105: getLogger()
106: .debug("Importing Lenya repository into JCR");
107: if (!JCR_LENYA_BASE_NAME.equals(firstNodeName)) {
108: throw new JCRImportException(
109: "Corrupt Lenya repository data file");
110: }
111: if (!session.itemExists(JCR_LENYA_ROOT)) {
112: throw new JCRImportException(
113: "Lenya JCR root not found ["
114: + JCR_LENYA_ROOT + "]");
115: }
116: // Remove existing Lenya repository.
117: String lenyaBasePath = JCR_LENYA_ROOT
118: + (JCR_LENYA_ROOT.endsWith("/") ? JCR_LENYA_BASE_NAME
119: : "/" + JCR_LENYA_BASE_NAME);
120: if (session.itemExists(lenyaBasePath)) {
121: Item jcrLenyaBase = session.getItem(lenyaBasePath);
122: jcrLenyaBase.remove();
123: session.save();
124: }
125:
126: // Import Lenya repository. Use workspace instead of session because of performance.
127: try {
128: ws.importXML(JCR_LENYA_ROOT, jcrImport
129: .getInputStream(),
130: ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
131: } catch (Exception e) {
132: throw new JCRImportException(
133: "Error importing data into workspace");
134: }
135: } else if (IMPORT_TARGET_PUBLICATION.equals(importTarget)) {
136: // Import Lenya publication
137: getLogger().debug(
138: "Importing Lenya publication into JCR");
139: if (!session.itemExists(JCR_LENYA_PUBLICATON_ROOT)) {
140: throw new JCRImportException(
141: "Lenya JCR root not found ["
142: + JCR_LENYA_ROOT + "]");
143: // TODO: Create JCR_LENYA_PUBLICATON_ROOT
144: }
145:
146: // Remove existing Lenya repository.
147: String lenyaPublicationPath = JCR_LENYA_PUBLICATON_ROOT
148: + (JCR_LENYA_PUBLICATON_ROOT.endsWith("/") ? firstNodeName
149: : "/" + firstNodeName);
150: if (session.itemExists(lenyaPublicationPath)) {
151: Item jcrPublicationBase = session
152: .getItem(lenyaPublicationPath);
153: jcrPublicationBase.remove();
154: session.save();
155: }
156:
157: // Import Lenya publication. Use workspace instead of session because of performance.
158: try {
159: ws.importXML(JCR_LENYA_PUBLICATON_ROOT, jcrImport
160: .getInputStream(),
161: ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
162: } catch (Exception e) {
163: throw new JCRImportException(
164: "Error importing data into workspace");
165: }
166: }
167: } catch (RepositoryException e) {
168: throw new JCRImportException(
169: "Error accessing JCR repository while importing data",
170: e);
171: }
172:
173: super .doExecute();
174: }
175:
176: /**
177: * @see org.apache.lenya.cms.usecase.AbstractUsecase#initParameters()
178: */
179: protected void initParameters() {
180: super .initParameters();
181: }
182:
183: private String getFirstNodeName(InputSource xmlInput)
184: throws SAXException, IOException {
185: XMLReader xmlReader = XMLReaderFactory.createXMLReader();
186:
187: FirstNodeNameHandler contentHandler = new FirstNodeNameHandler();
188: xmlReader.setContentHandler(contentHandler);
189: xmlReader.parse(xmlInput);
190: return contentHandler.getFirstNodeName();
191: }
192:
193: class FirstNodeNameHandler extends DefaultHandler {
194: private static final String NODE_NAME_Q_ATTR = "sv:name";
195:
196: private boolean isFirstElement = true;
197: private String firstNodeName = null;
198:
199: /**
200: * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
201: */
202: public void startElement(String uri, String localName,
203: String qName, Attributes attributes)
204: throws SAXException {
205: if (isFirstElement) {
206: firstNodeName = attributes.getValue(NODE_NAME_Q_ATTR);
207: isFirstElement = false;
208: } else {
209: super .startElement(uri, localName, qName, attributes);
210: }
211: }
212:
213: protected String getFirstNodeName() {
214: return firstNodeName;
215: }
216: }
217: }
|