001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */
018:
019: package de.schlund.pfixcore.editor2.core.spring.internal;
020:
021: import java.io.File;
022: import java.io.FileNotFoundException;
023: import java.io.IOException;
024: import java.util.ArrayList;
025: import java.util.Collection;
026: import java.util.HashMap;
027: import java.util.HashSet;
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Map;
031: import java.util.Set;
032:
033: import org.apache.log4j.Logger;
034: import org.w3c.dom.Document;
035: import org.xml.sax.SAXException;
036:
037: import de.schlund.pfixcore.editor2.core.dom.AbstractTarget;
038: import de.schlund.pfixcore.editor2.core.dom.AbstractTheme;
039: import de.schlund.pfixcore.editor2.core.dom.Image;
040: import de.schlund.pfixcore.editor2.core.dom.IncludePartThemeVariant;
041: import de.schlund.pfixcore.editor2.core.dom.Page;
042: import de.schlund.pfixcore.editor2.core.dom.Project;
043: import de.schlund.pfixcore.editor2.core.dom.Target;
044: import de.schlund.pfixcore.editor2.core.dom.TargetType;
045: import de.schlund.pfixcore.editor2.core.dom.Theme;
046: import de.schlund.pfixcore.editor2.core.dom.ThemeList;
047: import de.schlund.pfixcore.editor2.core.dom.Variant;
048: import de.schlund.pfixcore.editor2.core.exception.EditorIOException;
049: import de.schlund.pfixcore.editor2.core.exception.EditorParsingException;
050: import de.schlund.pfixcore.editor2.core.spring.FileSystemService;
051: import de.schlund.pfixcore.editor2.core.spring.ImageFactoryService;
052: import de.schlund.pfixcore.editor2.core.spring.IncludeFactoryService;
053: import de.schlund.pfixcore.editor2.core.spring.PathResolverService;
054: import de.schlund.pfixcore.editor2.core.spring.ProjectFactoryService;
055: import de.schlund.pfixcore.editor2.core.spring.TargetFactoryService;
056: import de.schlund.pfixcore.editor2.core.spring.ThemeFactoryService;
057: import de.schlund.pfixcore.editor2.core.spring.VariantFactoryService;
058: import de.schlund.pfixxml.resources.DocrootResource;
059: import de.schlund.pfixxml.resources.FileResource;
060: import de.schlund.pfixxml.resources.FileSystemResource;
061: import de.schlund.pfixxml.targets.AuxDependency;
062: import de.schlund.pfixxml.targets.AuxDependencyFile;
063: import de.schlund.pfixxml.targets.AuxDependencyImage;
064: import de.schlund.pfixxml.targets.AuxDependencyManager;
065: import de.schlund.pfixxml.targets.AuxDependencyTarget;
066: import de.schlund.pfixxml.targets.DependencyType;
067: import de.schlund.pfixxml.targets.PageInfo;
068: import de.schlund.pfixxml.targets.TargetDependencyRelation;
069: import de.schlund.pfixxml.targets.TargetGenerationException;
070: import de.schlund.pfixxml.targets.TargetImpl;
071: import de.schlund.pfixxml.targets.VirtualTarget;
072:
073: /**
074: * Implementation of Target using the Target object provided by the Pustefix
075: * generator.
076: *
077: * @author Sebastian Marsching <sebastian.marsching@1und1.de>
078: */
079: public class TargetPfixImpl extends AbstractTarget {
080:
081: private de.schlund.pfixxml.targets.Target pfixTarget;
082:
083: private Project project;
084:
085: private TargetFactoryService targetfactory;
086:
087: private ProjectFactoryService projectfactory;
088:
089: private VariantFactoryService variantfactory;
090:
091: private IncludeFactoryService includefactory;
092:
093: private ThemeFactoryService themefactory;
094:
095: private ImageFactoryService imagefactory;
096:
097: private PathResolverService pathresolver;
098:
099: private FileSystemService filesystem;
100:
101: public TargetPfixImpl(TargetFactoryService targetfactory,
102: ProjectFactoryService projectfactory,
103: VariantFactoryService variantfactory,
104: IncludeFactoryService includefactory,
105: ThemeFactoryService themefactory,
106: ImageFactoryService imagefactory,
107: PathResolverService pathresolver,
108: FileSystemService filesystem,
109: de.schlund.pfixxml.targets.Target pfixTarget,
110: Project project) {
111: this .pfixTarget = pfixTarget;
112: this .project = project;
113: this .targetfactory = targetfactory;
114: this .projectfactory = projectfactory;
115: this .variantfactory = variantfactory;
116: this .includefactory = includefactory;
117: this .themefactory = themefactory;
118: this .imagefactory = imagefactory;
119: this .pathresolver = pathresolver;
120: this .filesystem = filesystem;
121: }
122:
123: /*
124: * (non-Javadoc)
125: *
126: * @see de.schlund.pfixcore.editor2.core.dom.Target#getName()
127: */
128: public String getName() {
129: return this .pfixTarget.getTargetKey();
130: }
131:
132: /*
133: * (non-Javadoc)
134: *
135: * @see de.schlund.pfixcore.editor2.core.dom.Target#getType()
136: */
137: public TargetType getType() {
138: if (this .pfixTarget.getType() == de.schlund.pfixxml.targets.TargetType.XML_LEAF
139: || this .pfixTarget.getType() == de.schlund.pfixxml.targets.TargetType.XML_VIRTUAL) {
140: return TargetType.TARGET_XML;
141: } else if (this .pfixTarget.getType() == de.schlund.pfixxml.targets.TargetType.XSL_LEAF
142: || this .pfixTarget.getType() == de.schlund.pfixxml.targets.TargetType.XSL_VIRTUAL) {
143: return TargetType.TARGET_XSL;
144: }
145: // FIXME Do not return null but throw an exception
146: return null;
147: }
148:
149: /*
150: * (non-Javadoc)
151: *
152: * @see de.schlund.pfixcore.editor2.core.dom.Target#getContentXML()
153: */
154: public Document getContentXML() throws EditorIOException,
155: EditorParsingException {
156: File file;
157: if (this .pfixTarget.getType() == de.schlund.pfixxml.targets.TargetType.XML_LEAF
158: || this .pfixTarget.getType() == de.schlund.pfixxml.targets.TargetType.XSL_LEAF) {
159: file = new File(this .pathresolver.resolve(this .pfixTarget
160: .getTargetKey()));
161: } else {
162: // Make sure file is existing
163: try {
164: this .pfixTarget.getValue();
165: } catch (TargetGenerationException e) {
166: String msg = "Could not generate target "
167: + this .getName() + "!";
168: Logger.getLogger(this .getClass()).warn(msg);
169: }
170: FileResource targetFile = this .pfixTarget
171: .getTargetGenerator().getDisccachedir();
172: if (targetFile instanceof DocrootResource) {
173: String targetPath = ((DocrootResource) targetFile)
174: .getRelativePath();
175: file = new File(this .pathresolver.resolve(targetPath
176: + "/" + this .pfixTarget.getTargetKey()));
177: } else if (targetFile instanceof FileSystemResource) {
178: String targetPath = ((FileSystemResource) targetFile)
179: .getPathOnFileSystem();
180: file = new File(targetPath);
181: } else {
182: throw new RuntimeException(
183: "TargetGenerator returned non-docroot and non-filesystem-based path: "
184: + targetFile.toURI());
185: }
186:
187: }
188: Object lock = this .filesystem.getLock(file);
189: synchronized (lock) {
190: try {
191: return this .filesystem.readXMLDocumentFromFile(file);
192: } catch (FileNotFoundException e) {
193: String err = "File " + file.getAbsolutePath()
194: + " could not be found!";
195: Logger.getLogger(this .getClass()).error(err, e);
196: throw new EditorIOException(err, e);
197: } catch (SAXException e) {
198: String err = "Error during parsing file "
199: + file.getAbsolutePath() + "!";
200: Logger.getLogger(this .getClass()).error(err, e);
201: throw new EditorParsingException(err, e);
202: } catch (IOException e) {
203: String err = "File " + file.getAbsolutePath()
204: + " could not be read!";
205: Logger.getLogger(this .getClass()).error(err, e);
206: throw new EditorIOException(err, e);
207: }
208: }
209: }
210:
211: /*
212: * (non-Javadoc)
213: *
214: * @see de.schlund.pfixcore.editor2.core.dom.Target#getParentXML()
215: */
216: public Target getParentXML() {
217: if (this .pfixTarget.getXMLSource() == null) {
218: return null;
219: }
220: return this .targetfactory.getTargetFromPustefixTarget(
221: this .pfixTarget.getXMLSource(), this .getProject());
222: }
223:
224: /*
225: * (non-Javadoc)
226: *
227: * @see de.schlund.pfixcore.editor2.core.dom.Target#getParentXSL()
228: */
229: public Target getParentXSL() {
230: if (this .pfixTarget.getXSLSource() == null) {
231: return null;
232: }
233: return this .targetfactory.getTargetFromPustefixTarget(
234: this .pfixTarget.getXSLSource(), this .getProject());
235: }
236:
237: /*
238: * (non-Javadoc)
239: *
240: * @see de.schlund.pfixcore.editor2.core.dom.Target#getAuxDependencies()
241: */
242: public Collection<Target> getAuxDependencies() {
243: ArrayList<Target> deps = new ArrayList<Target>();
244: if (this .pfixTarget instanceof TargetImpl) {
245: TargetImpl vtarget = (TargetImpl) this .pfixTarget;
246: AuxDependencyManager auxmanager = vtarget
247: .getAuxDependencyManager();
248: if (auxmanager == null) {
249: return deps;
250: }
251:
252: for (Iterator<AuxDependency> i = auxmanager.getChildren()
253: .iterator(); i.hasNext();) {
254: AuxDependency auxdep = i.next();
255: if (auxdep.getType() == DependencyType.FILE) {
256: deps
257: .add(this .targetfactory
258: .getLeafTargetFromPustefixAuxDependency((AuxDependencyFile) auxdep));
259: } else if (auxdep.getType() == DependencyType.TARGET) {
260: de.schlund.pfixxml.targets.Target ptarget = ((AuxDependencyTarget) auxdep)
261: .getTarget();
262: deps.add(this .targetfactory
263: .getTargetFromPustefixTarget(ptarget,
264: this .project));
265: }
266: }
267: }
268:
269: return deps;
270: }
271:
272: /*
273: * (non-Javadoc)
274: *
275: * @see de.schlund.pfixcore.editor2.core.dom.Target#getIncludeDependencies(boolean)
276: */
277: public Collection<IncludePartThemeVariant> getIncludeDependencies(
278: boolean recursive) throws EditorParsingException {
279: ArrayList<IncludePartThemeVariant> deps = new ArrayList<IncludePartThemeVariant>();
280: if (this .pfixTarget instanceof VirtualTarget) {
281: if (recursive) {
282: Set<AuxDependency> alldeps = TargetDependencyRelation
283: .getInstance().getDependenciesForTarget(
284: this .pfixTarget);
285: if (alldeps != null) {
286: for (Iterator<AuxDependency> i = alldeps.iterator(); i
287: .hasNext();) {
288: AuxDependency aux = i.next();
289: if (aux.getType() == DependencyType.TEXT) {
290: IncludePartThemeVariant variant = this .includefactory
291: .getIncludePartThemeVariant(aux);
292: deps.add(variant);
293: }
294: }
295: }
296:
297: if (this .getParentXML() != null) {
298: deps.addAll(this .getParentXML()
299: .getIncludeDependencies(true));
300: }
301: if (this .getParentXSL() != null) {
302: deps.addAll(this .getParentXSL()
303: .getIncludeDependencies(true));
304: }
305:
306: } else {
307: VirtualTarget vtarget = (VirtualTarget) this .pfixTarget;
308: AuxDependencyManager auxmanager = vtarget
309: .getAuxDependencyManager();
310: if (auxmanager == null) {
311: String msg = "Could not get AuxDependencyManager for target "
312: + this .getName() + "!";
313: Logger.getLogger(this .getClass()).warn(msg);
314: return deps;
315: }
316:
317: for (Iterator<AuxDependency> i = auxmanager
318: .getChildren().iterator(); i.hasNext();) {
319: AuxDependency auxdep = i.next();
320: if (auxdep.getType() == DependencyType.TEXT) {
321: IncludePartThemeVariant variant = this .includefactory
322: .getIncludePartThemeVariant(auxdep);
323: deps.add(variant);
324: }
325: }
326: }
327:
328: return deps;
329: } else {
330: String msg = "Page target " + this .getName()
331: + " is no VirtualTarget!";
332: Logger.getLogger(this .getClass()).warn(msg);
333: return deps;
334: }
335: }
336:
337: /*
338: * (non-Javadoc)
339: *
340: * @see de.schlund.pfixcore.editor2.core.dom.Target#getImageDependencies(boolean)
341: */
342: public Collection<Image> getImageDependencies(boolean recursive)
343: throws EditorParsingException {
344: ArrayList<Image> deps = new ArrayList<Image>();
345: if (this .pfixTarget instanceof VirtualTarget) {
346: if (recursive) {
347: Set<AuxDependency> alldeps = TargetDependencyRelation
348: .getInstance().getDependenciesForTarget(
349: this .pfixTarget);
350: if (alldeps != null) {
351: for (Iterator<AuxDependency> i = alldeps.iterator(); i
352: .hasNext();) {
353: AuxDependency auxdep = i.next();
354: if (auxdep.getType() == DependencyType.IMAGE) {
355: Image img = this .imagefactory
356: .getImage(((AuxDependencyImage) auxdep)
357: .getPath()
358: .getRelativePath());
359: deps.add(img);
360: }
361: }
362: }
363:
364: if (this .getParentXML() != null) {
365: deps.addAll(this .getParentXML()
366: .getImageDependencies(true));
367: }
368: if (this .getParentXSL() != null) {
369: deps.addAll(this .getParentXSL()
370: .getImageDependencies(true));
371: }
372:
373: } else {
374: VirtualTarget vtarget = (VirtualTarget) this .pfixTarget;
375: AuxDependencyManager auxmanager = vtarget
376: .getAuxDependencyManager();
377: if (auxmanager == null) {
378: String msg = "Could not get AuxDependencyManager for target "
379: + this .getName() + "!";
380: Logger.getLogger(this .getClass()).warn(msg);
381: return deps;
382: }
383:
384: for (Iterator<AuxDependency> i = auxmanager
385: .getChildren().iterator(); i.hasNext();) {
386: AuxDependency auxdep = i.next();
387: if (auxdep.getType() == DependencyType.IMAGE) {
388: Image img = this .imagefactory
389: .getImage(((AuxDependencyImage) auxdep)
390: .getPath().getRelativePath());
391: deps.add(img);
392: }
393: }
394: }
395:
396: return deps;
397: } else {
398: String msg = "Page target " + this .getName()
399: + " is no VirtualTarget!";
400: Logger.getLogger(this .getClass()).warn(msg);
401: return deps;
402: }
403: }
404:
405: /*
406: * (non-Javadoc)
407: *
408: * @see de.schlund.pfixcore.editor2.core.dom.Target#getAffectedPages()
409: */
410: public Collection<Page> getAffectedPages() {
411: Collection<PageInfo> pageinfos = this .pfixTarget.getPageInfos();
412: HashSet<Page> pages = new HashSet<Page>();
413: for (Iterator<PageInfo> i2 = pageinfos.iterator(); i2.hasNext();) {
414: PageInfo pageinfo = i2.next();
415: if (pageinfo == null) {
416: continue;
417: }
418: Project project = projectfactory
419: .getProjectByPustefixTargetGenerator(pageinfo
420: .getTargetGenerator());
421: if (project == null) {
422: String msg = "Project for generator "
423: + pageinfo.getTargetGenerator().getName()
424: + " not found, omitting affected page!";
425: Logger.getLogger(this .getClass()).warn(msg);
426: continue;
427: }
428: Variant variant = null;
429: if (pageinfo.getVariant() != null) {
430: variant = this .variantfactory.getVariant(pageinfo
431: .getVariant());
432: }
433: Page page = project.getPage(pageinfo.getName(), variant);
434: if (page == null) {
435: String msg = "Could not get page "
436: + pageinfo.getName()
437: + ((variant != null) ? " with variant "
438: + variant.getName() : "")
439: + " from project " + project.getName()
440: + "! Omitting page!";
441: Logger.getLogger(this .getClass()).warn(msg);
442: continue;
443: }
444: pages.add(page);
445: }
446: return pages;
447: }
448:
449: /*
450: * (non-Javadoc)
451: *
452: * @see de.schlund.pfixcore.editor2.core.dom.Target#getProject()
453: */
454: public Project getProject() {
455: return this .project;
456: }
457:
458: public Map<String, Object> getParameters() {
459: Map<String, Object> map = this .pfixTarget.getParams();
460: if (map != null) {
461: Map<String, Object> rv = new HashMap<String, Object>();
462: // Remove non-String values, as they cannot be handeled correctly
463: for (Object key : map.keySet()) {
464: Object val = map.get(key);
465: if (val instanceof String) {
466: rv.put((String) key, (String) val);
467: }
468: }
469: return rv;
470: } else {
471: return new HashMap<String, Object>();
472: }
473: }
474:
475: public ThemeList getThemeList() {
476: if (this .pfixTarget instanceof VirtualTarget) {
477: VirtualTarget vtarget = (VirtualTarget) this .pfixTarget;
478: ThemeList themes = new ThemeListImpl(this .themefactory,
479: vtarget.getThemes());
480: return themes;
481: } else {
482: return new ThemeList() {
483:
484: public List<Theme> getThemes() {
485: ArrayList<Theme> list = new ArrayList<Theme>();
486: list.add(new AbstractTheme("default") {
487: });
488: return list;
489: }
490:
491: public boolean includesTheme(Theme theme) {
492: if (theme.getName().equals("default")) {
493: return true;
494: } else {
495: return false;
496: }
497: }
498:
499: public boolean themeOverridesTheme(Theme t1, Theme t2) {
500: return false;
501: }
502:
503: };
504: }
505: }
506:
507: de.schlund.pfixxml.targets.Target getPfixTarget() {
508: // This package level access method is used by
509: // IncludePartThemeVariantImpl to retrieve
510: // the Pustefix target object when lookup up
511: // dependencies
512: return this.pfixTarget;
513: }
514:
515: }
|