001package com.hfg.xml.msofficexml.part; 002 003import java.io.File; 004import java.io.Writer; 005import java.net.URL; 006import java.util.ArrayList; 007import java.util.List; 008 009import com.hfg.util.StringUtil; 010import com.hfg.util.collection.CollectionUtil; 011import com.hfg.util.FileUtil; 012import com.hfg.xml.XMLTag; 013import com.hfg.xml.msofficexml.OfficeOpenXmlDocument; 014import com.hfg.xml.msofficexml.OfficeOpenXmlRelationship; 015import com.hfg.xml.msofficexml.OfficeXML; 016import com.hfg.xml.msofficexml.RelationshipType; 017 018//------------------------------------------------------------------------------ 019/** 020 Represents an Office Open XML relationship part. 021 022 @author J. Alex Taylor, hairyfatguy.com 023 */ 024//------------------------------------------------------------------------------ 025// com.hfg XML/HTML Coding Library 026// 027// This library is free software; you can redistribute it and/or 028// modify it under the terms of the GNU Lesser General Public 029// License as published by the Free Software Foundation; either 030// version 2.1 of the License, or (at your option) any later version. 031// 032// This library is distributed in the hope that it will be useful, 033// but WITHOUT ANY WARRANTY; without even the implied warranty of 034// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 035// Lesser General Public License for more details. 036// 037// You should have received a copy of the GNU Lesser General Public 038// License along with this library; if not, write to the Free Software 039// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 040// 041// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 042// jataylor@hairyfatguy.com 043//------------------------------------------------------------------------------ 044 045public abstract class OfficeOpenXmlRelationshipPart extends OfficeXMLPart 046{ 047 // Because file paths may not be initially set, we delay rendering out the 048 // relationship XML until the last moment. 049 private List<OfficeOpenXmlRelationship> mRelationships; 050 051 private int mIndex = 1; 052 053 //--------------------------------------------------------------------------- 054 public OfficeOpenXmlRelationshipPart(OfficeOpenXmlDocument inOfficeDoc) 055 { 056 super(inOfficeDoc); 057 setRootNode(new XMLTag(OfficeXML.RELATIONSHIPS)); 058 } 059 060 //--------------------------------------------------------------------------- 061 public String addRelationship(OfficeOpenXmlRelationship inValue) 062 { 063 String id = null; 064 065 if (inValue != null) 066 { 067 id = inValue.getId(); 068 if (!StringUtil.isSet(id)) 069 { 070 id = generateId(); 071 inValue.setId(id); 072 } 073 074 if (null == mRelationships) 075 { 076 mRelationships = new ArrayList<>(25); 077 } 078 079 mRelationships.add(inValue); 080 081 if (inValue.getPart() != null) 082 { 083 // Register the content type 084 getParentDoc().getContentTypesPart().addOverride(inValue.getPart(), inValue.getType().getContentType()); 085 } 086 } 087 088 return id; 089 } 090 091 //--------------------------------------------------------------------------- 092 public String addRelationship(RelationshipType inType, OfficeXMLPart inPart) 093 { 094 OfficeOpenXmlRelationship relationship = new OfficeOpenXmlRelationship(); 095 relationship.setPart(inPart) 096 .setType(inType) 097 .setId(generateId()); 098 099 if (null == mRelationships) 100 { 101 mRelationships = new ArrayList<>(25); 102 } 103 104 mRelationships.add(relationship); 105 106 return relationship.getId(); 107 } 108 109 //--------------------------------------------------------------------------- 110 public String addRelationship(RelationshipType inType, File inTarget) 111 { 112 return addRelationship(new OfficeOpenXmlRelationship() 113 .setId(generateId()) 114 .setType(inType) 115 .setTarget(getRelativePath(inTarget))); 116 } 117 118 //--------------------------------------------------------------------------- 119 public String addHyperlink(URL inValue) 120 { 121 return addRelationship(new OfficeOpenXmlRelationship() 122 .setId(generateId()) 123 .setType(RelationshipType.HYPERLINK) 124 .setTarget(inValue.toString()) 125 .setTargetMode("External")); 126 } 127 128 //--------------------------------------------------------------------------- 129 public String addMedia(MediaPart inValue) 130 { 131// getParentDoc().addMediaPart(inValue); 132 133 return addRelationship(RelationshipType.IMAGE, inValue); 134 } 135 136 //--------------------------------------------------------------------------- 137 @Override 138 public void toXML(Writer inWriter) 139 { 140 // Because file paths may not be initially set, we delay rendering out the 141 // relationship XML until the last moment. 142 populateXML(); 143 super.toXML(inWriter); 144 } 145 146 //--------------------------------------------------------------------------- 147 @Override 148 public void toIndentedXML(Writer inWriter, int inInitialIndentLevel, int inIndentSize) 149 { 150 // Because file paths may not be initially set, we delay rendering out the 151 // relationship XML until the last moment. 152 populateXML(); 153 super.toIndentedXML(inWriter, inInitialIndentLevel, inIndentSize); 154 } 155 156 //--------------------------------------------------------------------------- 157 public void populateXML() 158 { 159 XMLTag rootNode = new XMLTag(OfficeXML.RELATIONSHIPS); 160 if (CollectionUtil.hasValues(mRelationships)) 161 { 162 for (OfficeOpenXmlRelationship relationship : mRelationships) 163 { 164 XMLTag relationshipTag = new XMLTag(OfficeXML.RELATIONSHIP); 165 relationshipTag.setAttribute(OfficeXML.ID_ATT, relationship.getId()); 166 relationshipTag.setAttribute(OfficeXML.TYPE_ATT, relationship.getType()); 167 168 String target = relationship.getTarget(); 169 if (null == target) 170 { 171 target = getRelativePath(relationship.getPart().getFile()); 172 } 173 174 relationshipTag.setAttribute(OfficeXML.TARGET_ATT, target); 175 176 String targetMode = relationship.getTargetMode(); 177 if (StringUtil.isSet(targetMode)) 178 { 179 relationshipTag.setAttribute(OfficeXML.TARGET_MODE_ATT, targetMode); 180 } 181 182 183 rootNode.addSubtag(relationshipTag); 184 } 185 } 186 187 setRootNode(rootNode); 188 } 189 190 //--------------------------------------------------------------------------- 191 protected String generateId() 192 { 193 return "rId" + (mIndex++); 194 } 195/* 196 //--------------------------------------------------------------------------- 197 private String getRelativePath(File inFile) 198 { 199 String relativePath = FileUtil.getRelativePath(inFile, getFile().getParentFile()); 200 if (relativePath.startsWith("./")) 201 { 202 relativePath = relativePath.substring(2); 203 } 204 205 return relativePath; 206// String path = inFile.getPath(); 207// if (path.startsWith(getFile().getParentFile().getParentFile().getPath())) 208// { 209// path = path.substring(getFile().getParentFile().getParentFile().getPath().length() + 1); 210// } 211// 212// return path; 213 } 214*/ 215 //--------------------------------------------------------------------------- 216 protected String getRelativePath(File inFile) 217 { 218 String path = inFile.getPath(); 219 if (path.startsWith(getFile().getParentFile().getParentFile().getPath())) 220 { 221 path = path.substring(getFile().getParentFile().getParentFile().getPath().length() + 1); 222 } 223 224 // Also ensure that the file paths consistently use '/' instead of '\' even if 225 // generated on a Windoze system. Windoze separators were causing files to appear corrupt. 226 return FileUtil.convertSeparatorsToUnix(path); 227 } 228 229}