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<Object> schemas = root.elements("schema");
073        Element src = null;
074        if (schemas != null) {
075            for (Object s : schemas) {
076                Element schema = (Element) s;
077                String name = schema.attribute("name").getText();
078
079                if (srcSchemaName.equalsIgnoreCase(name)) {
080                    src = schema.element(getUnprefixedName(srcField));
081                    src.detach();
082                }
083            }
084
085            Element dstSchema = null;
086            if (dstField == null || src == null) {
087                // NOP
088            } else {
089                for (Object s : schemas) {
090                    Element schema = (Element) s;
091                    String name = schema.attribute("name").getText();
092                    if (dstSchemaName.equalsIgnoreCase(name)) {
093                        dstSchema = schema;
094                        break;
095                    }
096                }
097                if (dstSchema == null) {
098                    dstSchema = root.addElement("schema");
099                    dstSchema.addAttribute("name", dstSchemaName);
100                }
101                Element dst = dstSchema.element(getUnprefixedName(dstField));
102                if (dst == null) {
103                    String prefix = getPrefix(dstField);
104                    if (prefix == null || dstSchema.getNamespaceForPrefix(prefix) == null) {
105                        dst = dstSchema.addElement(getUnprefixedName(dstField));
106                    } else {
107                        dst = dstSchema.addElement(dstField);
108                    }
109                }
110                for (Object sub : src.elements()) {
111                    Element e = (Element) sub;
112                    e.detach();
113                    dst.add(e);
114                }
115                String txt = src.getText();
116                if (txt != null) {
117                    dst.addText(txt);
118                }
119
120            }
121
122        }
123        return true;
124    }
125
126}