001/*
002 * Copyright (c) 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Nuxeo - initial API and implementation
011 *
012 */
013package org.nuxeo.ecm.core.io.impl.transformers;
014
015import java.io.IOException;
016import java.util.List;
017
018import org.dom4j.Element;
019import org.nuxeo.ecm.core.io.DocumentTransformer;
020import org.nuxeo.ecm.core.io.ExportedDocument;
021
022/**
023 * Rename / translate a field
024 *
025 * @since 7.4
026 */
027public class FieldMapper implements DocumentTransformer {
028
029    protected final String srcSchemaName;
030
031    protected final String dstSchemaName;
032
033    protected final String srcField;
034
035    protected final String dstField;
036
037    public FieldMapper(String srcSchemaName, String srcField, String dstSchemaName, String dstField) {
038        this.srcSchemaName = srcSchemaName;
039        if (dstSchemaName == null && dstField != null) {
040            this.dstSchemaName = srcSchemaName;
041        } else {
042            this.dstSchemaName = dstSchemaName;
043        }
044        this.srcField = srcField;
045        this.dstField = dstField;
046
047    }
048
049    protected String getUnprefixedName(String name) {
050
051        int idx = name.indexOf(":");
052        if (idx > 0) {
053            return name.substring(idx + 1);
054        }
055        return name;
056    }
057
058    protected String getPrefix(String name) {
059
060        int idx = name.indexOf(":");
061        if (idx > 0) {
062            return name.substring(0, idx);
063        }
064        return null;
065    }
066
067    @Override
068    public boolean transform(ExportedDocument xdoc) throws IOException {
069
070        Element root = xdoc.getDocument().getRootElement();
071
072        List<Element> schemas = root.elements("schema");
073        Element src = null;
074        if (schemas != null) {
075            for (Element schema : schemas) {
076                String name = schema.attribute("name").getText();
077
078                if (srcSchemaName.equalsIgnoreCase(name)) {
079                    src = schema.element(getUnprefixedName(srcField));
080                    src.detach();
081                }
082            }
083
084            Element dstSchema = null;
085            if (dstField == null || src == null) {
086                // NOP
087            } else {
088                for (Object s : schemas) {
089                    Element schema = (Element) s;
090                    String name = schema.attribute("name").getText();
091                    if (dstSchemaName.equalsIgnoreCase(name)) {
092                        dstSchema = schema;
093                        break;
094                    }
095                }
096                if (dstSchema == null) {
097                    dstSchema = root.addElement("schema");
098                    dstSchema.addAttribute("name", dstSchemaName);
099                }
100                Element dst = dstSchema.element(getUnprefixedName(dstField));
101                if (dst == null) {
102                    String prefix = getPrefix(dstField);
103                    if (prefix == null || dstSchema.getNamespaceForPrefix(prefix) == null) {
104                        dst = dstSchema.addElement(getUnprefixedName(dstField));
105                    } else {
106                        dst = dstSchema.addElement(dstField);
107                    }
108                }
109                for (Object sub : src.elements()) {
110                    Element e = (Element) sub;
111                    e.detach();
112                    dst.add(e);
113                }
114                String txt = src.getText();
115                if (txt != null) {
116                    dst.addText(txt);
117                }
118
119            }
120
121        }
122        return true;
123    }
124
125}