001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.xml.export;
019:
020: import java.io.BufferedWriter;
021: import java.io.File;
022: import java.io.FileOutputStream;
023: import java.io.IOException;
024: import java.io.OutputStreamWriter;
025: import java.io.Writer;
026: import java.util.Iterator;
027: import java.util.Stack;
028:
029: import org.apache.log4j.Logger;
030:
031: import de.finix.contelligent.CallData;
032: import de.finix.contelligent.Component;
033: import de.finix.contelligent.ComponentManager;
034: import de.finix.contelligent.ComponentNotFoundException;
035: import de.finix.contelligent.ComponentPath;
036: import de.finix.contelligent.Container;
037: import de.finix.contelligent.Contelligent;
038: import de.finix.contelligent.Type;
039: import de.finix.contelligent.core.ComponentFactory;
040: import de.finix.contelligent.core.security.ContelligentSecurityManager;
041: import de.finix.contelligent.exception.ContelligentException;
042: import de.finix.contelligent.logging.LoggingService;
043:
044: /**
045: * Utility class to create an XML representation of the whole Contelligent
046: * system in a local file system. The system gets exported in an exploded
047: * structure where every type, component or principal-group is written in a
048: * separate file.
049: */
050: final public class LocalXMLExport {
051:
052: final static Logger log = LoggingService
053: .getLogger(LocalXMLExport.class);
054:
055: final public static String TYPES_SUBDIR = "types";
056:
057: final public static String COMPONENTS_SUBDIR = "components";
058:
059: final public static String FILES_SUBDIR = "files";
060:
061: final public static String ROLES_SUBDIR = "roles";
062:
063: final public static String USERS_SUBDIR = "users";
064:
065: final private TypeXMLPolicy typePolicy;
066:
067: final private File baseDir, componentsDir, filesDir, typesDir,
068: rolesDir, usersDir;
069:
070: public LocalXMLExport(File exportDir, TypeXMLPolicy typePolicy)
071: throws IOException {
072: this .typePolicy = typePolicy;
073: this .baseDir = createAndCheckDir(exportDir, true);
074: typesDir = createAndCheckDir(new File(baseDir, TYPES_SUBDIR),
075: false);
076: componentsDir = createAndCheckDir(new File(baseDir,
077: COMPONENTS_SUBDIR), false);
078: filesDir = createAndCheckDir(new File(baseDir, FILES_SUBDIR),
079: false);
080: rolesDir = createAndCheckDir(new File(baseDir, ROLES_SUBDIR),
081: false);
082: usersDir = createAndCheckDir(new File(baseDir, USERS_SUBDIR),
083: false);
084: }
085:
086: public LocalXMLExport(File exportDir) throws IOException {
087: this (exportDir, new DefaultTypeXMLPolicy());
088: }
089:
090: public File getFilesDir() {
091: return filesDir;
092: }
093:
094: public File getTypesDir() {
095: return typesDir;
096: }
097:
098: public File getRolesDir() {
099: return rolesDir;
100: }
101:
102: public File getUsersDir() {
103: return usersDir;
104: }
105:
106: public File getComponentsDir() {
107: return componentsDir;
108: }
109:
110: /**
111: * Describe <code>exportSystem</code> method here.
112: *
113: * @param contelligent
114: * a <code>Contelligent</code> value
115: * @param fileBase
116: * a <code>File</code> value
117: * @param callData
118: * a <code>CallData</code> value
119: * @exception Exception
120: * if an error occurs
121: */
122: public void exportSystem(Contelligent contelligent,
123: CallData callData) throws Exception {
124: final ComponentPath rootPath = ComponentPath.ROOT_PATH;
125: ContelligentSecurityManager securityManager = ContelligentSecurityManager
126: .getInstance();
127:
128: Iterator groups = securityManager.getRegisteredRoleGroupIds()
129: .iterator();
130: while (groups.hasNext()) {
131: String groupId = (String) groups.next();
132: exportPrincipalGroup(rolesDir, groupId, securityManager);
133: }
134:
135: groups = securityManager.getRegisteredUserGroupIds().iterator();
136: while (groups.hasNext()) {
137: String groupId = (String) groups.next();
138: exportPrincipalGroup(usersDir, groupId, securityManager);
139: }
140:
141: exportAllTypes(contelligent, typesDir);
142: exportAllComponents(contelligent, callData, componentsDir,
143: filesDir, rootPath);
144:
145: log.info("successfully exported system to directory '"
146: + baseDir + "'!");
147: }
148:
149: public void exportAllTypes(Contelligent contelligent, File targetDir)
150: throws Exception {
151: ComponentFactory componentFactory = contelligent
152: .getComponentManagerHierarchy().getComponentFactory();
153: TypeXMLWriter typeWriter = new TypeXMLWriter(typePolicy);
154: Iterator typeNames = componentFactory.typeNames().iterator();
155: while (typeNames.hasNext()) {
156: String typeName = (String) typeNames.next();
157: Type type = componentFactory.getType(typeName);
158: exportType(typeWriter, type, targetDir);
159: }
160: }
161:
162: public static String typeNameToFileName(String typeName) {
163: return (typeName.replace('.', File.separatorChar) + ".xml");
164: }
165:
166: public static String principalGroupIdToFileName(String groupId) {
167: return (groupId + ".xml");
168: }
169:
170: public boolean exportType(TypeXMLWriter typeXMLWriter, Type type,
171: File targetDir) throws IOException {
172: final boolean debugEnabled = log.isDebugEnabled();
173: String typeName = type.getName();
174: String fileName = typeNameToFileName(typeName);
175: File typeFile = new File(targetDir, fileName);
176: boolean dirsCreated = typeFile.getParentFile().mkdirs();
177:
178: Writer writer = null;
179: try {
180: if (debugEnabled)
181: log.debug("writing type '" + typeName + "' to file '"
182: + typeFile + "' ...");
183: writer = new BufferedWriter(new OutputStreamWriter(
184: new FileOutputStream(typeFile), "UTF-8"));
185: typeXMLWriter.write(new Type[] { type }, writer, false);
186: return dirsCreated;
187: } finally {
188: if (writer != null) {
189: try {
190: writer.close();
191: } catch (Exception e) {
192: log
193: .warn(
194: "exportType() - exception while closing writer: ",
195: e);
196: }
197: }
198: }
199: }
200:
201: public void exportAllComponents(Contelligent contelligent,
202: CallData callData, File baseDir, File binaryBaseDir,
203: ComponentPath rootPath) throws Exception {
204: final boolean debugEnabled = log.isDebugEnabled();
205: final ComponentManager manager = contelligent
206: .getRootComponentManager();
207: ComponentPath componentPath = rootPath;
208: Component component = null;
209:
210: ComponentXMLPolicy xmlPolicy = new SingleComponentXMLPolicy(
211: binaryBaseDir);
212: component = manager
213: .getComponent(componentPath, callData, false);
214: final Stack componentStack = new Stack();
215: componentStack.push(component);
216:
217: while (!componentStack.empty()) {
218: component = (Component) componentStack.pop();
219: componentPath = component.getComponentContext().getPath();
220: if (ComponentPath.ROOT_PATH.equals(componentPath)) {
221: log.info("skipping export of root-component ...");
222: } else {
223: File file = new File(baseDir,
224: (componentPath.toString() + ".xml"));
225: file.getParentFile().mkdirs();
226:
227: Writer out = new BufferedWriter(new OutputStreamWriter(
228: new FileOutputStream(file), "UTF-8"));
229: ComponentXMLWriter xmlWriter = new ComponentXMLWriter(
230: out, xmlPolicy);
231: xmlWriter.write(component);
232: out.close();
233: if (debugEnabled)
234: log.debug("writing component '" + componentPath
235: + "' to file '" + file + "' ...");
236: }
237: if ((component instanceof Container)
238: && ((Container) component).getHasChildren()) {
239: File dir = new File(baseDir, componentPath.toString());
240: dir.mkdir();
241: Container container = (Container) component;
242: Iterator subNames = container.getSubcomponentNames();
243: while (subNames.hasNext()) {
244: String subComponentName = (String) subNames.next();
245: try {
246: Component sub = manager.getSubcomponent(
247: container, subComponentName, callData,
248: false);// don't
249: // follow
250: // links
251: componentStack.push(sub);
252: } catch (ComponentNotFoundException e) {
253: log
254: .error("subcomponent '"
255: + subComponentName
256: + "' of container '"
257: + container
258: + "' not found although we used method 'getSubcomponentNames()' (skipping this tree): "
259: + e);
260: }
261: }
262: }
263: }
264: }
265:
266: public void exportPrincipalGroup(File baseDir, String groupId,
267: ContelligentSecurityManager securityManager)
268: throws ContelligentException, IOException {
269: Writer writer = null;
270: try {
271: File file = new File(baseDir,
272: principalGroupIdToFileName(groupId));
273: writer = new BufferedWriter(new OutputStreamWriter(
274: new FileOutputStream(file), "UTF-8"));
275: securityManager.exportPrincipalData(groupId, writer);
276: writer.close();
277: } finally {
278: if (writer != null) {
279: try {
280: writer.close();
281: } catch (Exception e) {
282: log
283: .warn(
284: "exportPrincipalGroup() - exception while closing writer: ",
285: e);
286: }
287: }
288: }
289: }
290:
291: // only all categories at once can be exported
292: /*
293: * private void exportCategories(CategoryManager categoryManager, Writer
294: * writer) throws IOException { DTDCatalog dtdCatalog =
295: * DTDCatalog.getInstance(); StringBuffer output = new StringBuffer(160);
296: * output.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE
297: * ").append(DTDCatalog.CATEGORY_DEFINITION) .append(" PUBLIC
298: * \"").append(dtdCatalog.getPublicId(DTDCatalog.CATEGORY_DEFINITION))
299: * .append("\" \"").append(DTDCatalog.PUBLICID_URLPREFIX)
300: * .append(dtdCatalog.getFileName(DTDCatalog.CATEGORY_DEFINITION)).append("\">\n\n")
301: * .append("<").append(DTDCatalog.CATEGORY_DEFINITION).append(">\n");
302: *
303: * writer.write(output.toString());
304: *
305: * String[] categoryNames = categoryManager.getCategoryNames(); for (int
306: * i=0; i<categoryNames.length; i++) {
307: * writer.write(categoryManager.categoryToXML(categoryNames[i])); }
308: *
309: * writer.write("</" + DTDCatalog.CATEGORY_DEFINITION + ">\n");
310: * writer.flush(); }
311: */
312:
313: private File createAndCheckDir(File dir, boolean recursive)
314: throws IOException {
315: if (recursive) {
316: dir.mkdirs();
317: } else {
318: dir.mkdir();
319: }
320: if (!dir.isDirectory()) {
321: throw new IOException("Could not create directory '" + dir
322: + "'!");
323: }
324: return dir;
325: }
326:
327: }
|