Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactored output generation by moving all specifics to OutputGenerat…

…or subclasses.

Each concrete output generator is implemented as a subclass of OutputGenerator instead of extending DoxygenConverter by another category. This results in much cleaner class structure and responsibility division as well as much more decoupling between different output generation objects.
  • Loading branch information...
commit 3a46c43e8e138bdb5bc78b0e344cfd29f977fb48 1 parent 8b9c738
@tomaz authored
Showing with 2,016 additions and 1,606 deletions.
  1. +12 −0 CommandLineParser.h
  2. +9 −0 CommandLineParser.m
  3. +43 −0 Constants.h
  4. +60 −0 Constants.m
  5. +40 −15 DoxygenConverter+DocSet.h → DocSetOutputGenerator.h
  6. +64 −16 DoxygenConverter+DocSet.m → DocSetOutputGenerator.m
  7. +0 −38 DoxygenConverter+CleanOutput.h
  8. +0 −74 DoxygenConverter+CleanOutput.m
  9. +0 −65 DoxygenConverter+Helpers.h
  10. +0 −40 DoxygenConverter+Helpers.m
  11. +9 −48 DoxygenConverter.h
  12. +56 −109 DoxygenConverter.m
  13. +28 −20 DoxygenConverter+Doxygen.h → DoxygenOutputGenerator.h
  14. +33 −7 DoxygenConverter+Doxygen.m → DoxygenOutputGenerator.m
  15. +130 −267 OutputGenerator.h
  16. +69 −557 OutputGenerator.m
  17. +68 −0 OutputInfoProvider.h
  18. +46 −0 OutputProcessing.h
  19. +67 −0 Systemator.h
  20. +64 −1 Systemator.m
  21. +4 −36 XHTMLOutputGenerator.h
  22. +51 −44 XHTMLOutputGenerator.m
  23. +4 −15 OutputGenerator+GeneralParsingAPI.h → XMLBasedOutputGenerator+GeneralParsingAPI.h
  24. +3 −11 OutputGenerator+GeneralParsingAPI.m → XMLBasedOutputGenerator+GeneralParsingAPI.m
  25. +4 −4 OutputGenerator+HierarchyParsingAPI.h → XMLBasedOutputGenerator+HierarchyParsingAPI.h
  26. +4 −4 OutputGenerator+HierarchyParsingAPI.m → XMLBasedOutputGenerator+HierarchyParsingAPI.m
  27. +15 −15 OutputGenerator+HierarchySubclassAPI.h → XMLBasedOutputGenerator+HierarchySubclassAPI.h
  28. +3 −3 OutputGenerator+HierarchySubclassAPI.m → XMLBasedOutputGenerator+HierarchySubclassAPI.m
  29. +4 −4 OutputGenerator+IndexParsingAPI.h → XMLBasedOutputGenerator+IndexParsingAPI.h
  30. +4 −4 OutputGenerator+IndexParsingAPI.m → XMLBasedOutputGenerator+IndexParsingAPI.m
  31. +15 −15 OutputGenerator+IndexSubclassAPI.h → XMLBasedOutputGenerator+IndexSubclassAPI.h
  32. +3 −3 OutputGenerator+IndexSubclassAPI.m → XMLBasedOutputGenerator+IndexSubclassAPI.m
  33. +4 −4 OutputGenerator+ObjectParsingAPI.h → XMLBasedOutputGenerator+ObjectParsingAPI.h
  34. +4 −4 OutputGenerator+ObjectParsingAPI.m → XMLBasedOutputGenerator+ObjectParsingAPI.m
  35. +37 −37 OutputGenerator+ObjectSubclassAPI.h → XMLBasedOutputGenerator+ObjectSubclassAPI.h
  36. +3 −3 OutputGenerator+ObjectSubclassAPI.m → XMLBasedOutputGenerator+ObjectSubclassAPI.m
  37. +224 −0 XMLBasedOutputGenerator.h
  38. +639 −0 XMLBasedOutputGenerator.m
  39. +29 −35 DoxygenConverter+CleanXML.h → XMLOutputGenerator.h
  40. +66 −30 DoxygenConverter+CleanXML.m → XMLOutputGenerator.m
  41. +98 −78 appledoc.xcodeproj/project.pbxproj
View
12 CommandLineParser.h
@@ -27,6 +27,7 @@ as a singleton.
{
NSMutableArray* commandLineArguments;
NSMutableDictionary* parameters;
+ NSString* outputDoxygenXMLPath;
NSString* globalTemplatesPath;
}
@@ -225,6 +226,17 @@ and @c docsetutil. */
/// @name Properties - internal
//////////////////////////////////////////////////////////////////////////////////////////
+/** The full path to the doxygen output files.
+
+Note that this property is handled differently from others - by default it is set to
+@c outputPath(), however doxygen handler should read the actual value from the doxygen
+configuration file and set it here so that the rest of the application can use it.
+
+Since doxygen generation is the first this that gets generated, the path is properly
+setup for all dependent generators automatically.
+*/
+@property(copy) NSString* outputDoxygenXMLPath;
+
/** The full path to the output clean XML files. */
@property(readonly) NSString* outputCleanXMLPath;
View
9 CommandLineParser.m
@@ -410,6 +410,9 @@ - (void) postProcessCommandLineArguments
[self replaceTemplatePlaceholdersForKey:kTKCmdOutputDocSetResourcesPathKey];
[self replaceTemplatePlaceholdersForKey:kTKCmdOutputDocSetDocumentsPathKey];
+ // Setup the default doxygen output XML path.
+ self.outputDoxygenXMLPath = self.outputPath;
+
// Make sure the documentation set bundle ID ends with .docset.
if (![self.docsetBundleID hasSuffix:@".docset"])
{
@@ -1016,4 +1019,10 @@ - (NSString*) outputDocSetDocumentsPath
return [parameters objectForKey:kTKCmdOutputDocSetDocumentsPathKey];
}
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Synthetized properties
+//////////////////////////////////////////////////////////////////////////////////////////
+
+@synthesize outputDoxygenXMLPath;
+
@end
View
43 Constants.h
@@ -0,0 +1,43 @@
+//
+// Constants.h
+// appledoc
+//
+// Created by Tomaz Kragelj on 12.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+extern NSString* kTKConverterException;
+extern NSString* kTKPlaceholderExtension;
+
+extern NSString* kTKDirClasses;
+extern NSString* kTKDirCategories;
+extern NSString* kTKDirProtocols;
+extern NSString* kTKDirCSS;
+extern NSString* kTKDirDocSet;
+
+extern NSString* kTKDataMainIndexKey;
+extern NSString* kTKDataMainHierarchyKey;
+extern NSString* kTKDataMainHierarchiesKey;
+extern NSString* kTKDataMainObjectsKey;
+extern NSString* kTKDataMainDirectoriesKey;
+
+extern NSString* kTKDataHierarchyObjectNameKey;
+extern NSString* kTKDataHierarchyObjectDataKey;
+extern NSString* kTKDataHierarchyChildrenKey;
+extern NSString* kTKDataHierarchyTempKey;
+
+extern NSString* kTKDataObjectNameKey;
+extern NSString* kTKDataObjectKindKey;
+extern NSString* kTKDataObjectClassKey;
+extern NSString* kTKDataObjectMarkupKey;
+extern NSString* kTKDataObjectMembersKey;
+extern NSString* kTKDataObjectParentKey;
+extern NSString* kTKDataObjectRelDirectoryKey;
+extern NSString* kTKDataObjectRelPathKey;
+extern NSString* kTKDataObjectDoxygenFilenameKey;
+
+extern NSString* kTKDataMemberNameKey;
+extern NSString* kTKDataMemberPrefixKey;
+extern NSString* kTKDataMemberSelectorKey;
View
60 Constants.m
@@ -0,0 +1,60 @@
+//
+// Constants.m
+// appledoc
+//
+// Created by Tomaz Kragelj on 12.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
+//
+
+#import "Constants.h"
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Exception names
+//////////////////////////////////////////////////////////////////////////////////////////
+
+NSString* kTKConverterException = @"TKConverterException";
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Placeholder strings
+//////////////////////////////////////////////////////////////////////////////////////////
+
+NSString* kTKPlaceholderExtension = @"$EXTENSION";
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Common directory structure
+//////////////////////////////////////////////////////////////////////////////////////////
+
+NSString* kTKDirClasses = @"Classes";
+NSString* kTKDirCategories = @"Categories";
+NSString* kTKDirProtocols = @"Protocols";
+NSString* kTKDirCSS = @"css";
+NSString* kTKDirDocSet = @"docset";
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Database keys
+//////////////////////////////////////////////////////////////////////////////////////////
+
+NSString* kTKDataMainIndexKey = @"Index"; // NSXMLDocument
+NSString* kTKDataMainHierarchyKey = @"Hierarchy"; // NSXMLDocument
+NSString* kTKDataMainHierarchiesKey = @"Hierarchies"; // NSDictionary
+NSString* kTKDataMainObjectsKey = @"Objects"; // NSDictionary
+NSString* kTKDataMainDirectoriesKey = @"Directories"; // NSDictionary
+
+NSString* kTKDataHierarchyObjectNameKey = @"ObjectName"; // NSString
+NSString* kTKDataHierarchyObjectDataKey = @"ObjectData"; // NSDictionary
+NSString* kTKDataHierarchyChildrenKey = @"Children"; // NSString
+NSString* kTKDataHierarchyTempKey = @"TEMPORARY"; // NSNumber / BOOL
+
+NSString* kTKDataObjectNameKey = @"ObjectName"; // NSString
+NSString* kTKDataObjectKindKey = @"ObjectKind"; // NSString
+NSString* kTKDataObjectClassKey = @"ObjectClass"; // NSString
+NSString* kTKDataObjectMarkupKey = @"CleanedMarkup"; // NSXMLDocument
+NSString* kTKDataObjectMembersKey = @"Members"; // NSDictionary
+NSString* kTKDataObjectParentKey = @"Parent"; // NSString
+NSString* kTKDataObjectRelDirectoryKey = @"RelativeDirectory"; // NSString
+NSString* kTKDataObjectRelPathKey = @"RelativePath"; // NSString
+NSString* kTKDataObjectDoxygenFilenameKey = @"DoxygenMarkupFilename"; // NSString
+
+NSString* kTKDataMemberNameKey = @"Name"; // NSString
+NSString* kTKDataMemberPrefixKey = @"Prefix"; // NSString
+NSString* kTKDataMemberSelectorKey = @"Selector"; // NSString
View
55 DoxygenConverter+DocSet.h → DocSetOutputGenerator.h
@@ -1,26 +1,34 @@
//
-// DoxygenConverter+DocSet.h
+// DocSetOutputGenerator.h
// appledoc
//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
+// Created by Tomaz Kragelj on 11.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
//
-#import <Foundation/Foundation.h>
-#import "DoxygenConverter.h"
+#import "OutputGenerator.h"
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
-/** Implements documentation set related functionality for @c DoxygenConverter class.
+/** Defines a concrete @c OutputGenerator which generates documentation set.
-This category creates the documentation set info plist and all required files required for
-indexing the documentation set, it handles the indexing itself and prepares the
-documentation set bundle as well as installs it to the @c Xcode documentation.
+The generator depends on @c XMLOutputGenerator and @c XHTMLOutputGenerator output. It
+generates the documentation set source plist, index and nodes XML source files, invokes
+indexing through the @c docsetutils command line utility and installs the documentation
+set to the Xcode documentation window.
+
+Since the @c DocSetOutputGenerator doesn't generate the actual content files itself, it
+must be given the locations, names and extensions of the source files. This should be
+set through the @c documentationFilesInfoProvider() property before generation starts. If the
+clients forget to set this property, generation will fail immediately.
*/
-@interface DoxygenConverter (DocSet)
+@interface DocSetOutputGenerator : OutputGenerator
+{
+ id<OutputInfoProvider> documentationFilesInfoProvider;
+}
//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Documentation set creation handling
+/// @name Documentation set handling
//////////////////////////////////////////////////////////////////////////////////////////
/** Creates the DocSet source plist file.
@@ -29,7 +37,8 @@ This file is used when creating the documentation set. The file is only created
doesn't exist yet. If it exists, this method will exit without doing anything. This
allows the user to change the data in the file as he see fit after it was created.
-This message is automatically sent from @c DoxygenConverter::convert() in the proper order.
+This message is automatically sent from @c generateSpecificOutput() in the proper order.
+It is not designed to be sent manually from the clients.
@exception NSException Thrown if creating the plist file fails.
@see createDocSetNodesFile
@@ -44,7 +53,8 @@ The Nodes.xml file describes the structure of the documentation set and is used
create a table of contents that users see in the Xcode documentation window. This file
is required when compiling the documentation set.
-This message is automatically sent from @c DoxygenConverter::convert() in the proper order.
+This message is automatically sent from @c generateSpecificOutput() in the proper order.
+It is not designed to be sent manually from the clients.
@exception NSException Thrown if creation fails.
@see createDocSetSourcePlistFile
@@ -59,7 +69,8 @@ This message is automatically sent from @c DoxygenConverter::convert() in the pr
The Tokens.xml file associate symbol names with locations in the documentation files.
This file is used for creating the symbol index for the documentation set.
-This message is automatically sent from @c DoxygenConverter::convert() in the proper order.
+This message is automatically sent from @c generateSpecificOutput() in the proper order.
+It is not designed to be sent manually from the clients.
@exception NSException Thrown if creation fails.
@see createDocSetSourcePlistFile
@@ -75,12 +86,14 @@ have been created. It will copy all html files created in @c createCleanOutputDo
to the DocSet output directory and will invoke the indexing of the files with the help of
nodes and tokes files.
-This message is automatically sent from @c DoxygenConverter::convert() in the proper order.
+This message is automatically sent from @c generateSpecificOutput() in the proper order.
+It is not designed to be sent manually from the clients.
@exception NSException Thrown if creation fails.
@see createDocSetSourcePlistFile
@see createDocSetNodesFile
@see createDocSetTokesFile
+@see addDocSetNodeToElement:fromHierarchyData:
*/
- (void) createDocSetBundle;
@@ -98,4 +111,16 @@ will recursively add all subnodes as well.
- (void) addDocSetNodeToElement:(NSXMLElement*) parent
fromHierarchyData:(NSDictionary*) data;
+//////////////////////////////////////////////////////////////////////////////////////////
+/// @name Properties
+//////////////////////////////////////////////////////////////////////////////////////////
+
+/** Sets or returns the @c OutputInfoProvider conformer that provides information about
+source files.
+
+@warning Clients need to set this before starting output generation. If they fail to
+ provide a valid object, generation immediately fails with an exception.
+*/
+@property(retain) id<OutputInfoProvider> documentationFilesInfoProvider;
+
@end
View
80 DoxygenConverter+DocSet.m → DocSetOutputGenerator.m
@@ -1,18 +1,63 @@
//
-// DoxygenConverter+DocSet.m
+// DocSetOutputGenerator.m
// appledoc
//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
+// Created by Tomaz Kragelj on 11.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
//
-#import "DoxygenConverter+DocSet.h"
-#import "XHTMLOutputGenerator.h"
+#import "DocSetOutputGenerator.h"
#import "CommandLineParser.h"
#import "LoggingProvider.h"
#import "Systemator.h"
-@implementation DoxygenConverter (DocSet)
+@implementation DocSetOutputGenerator
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Specific output generation entry points
+//////////////////////////////////////////////////////////////////////////////////////////
+
+//----------------------------------------------------------------------------------------
+- (BOOL) isOutputGenerationEnabled
+{
+ return cmd.createDocSet;
+}
+
+//----------------------------------------------------------------------------------------
+- (void) generateSpecificOutput
+{
+ if (!self.documentationFilesInfoProvider)
+ [Systemator throwExceptionWithName:kTKConverterException
+ withDescription:@"documentationFilesInfoProvider not set"];
+
+ [self createDocSetSourcePlistFile];
+ [self createDocSetNodesFile];
+ [self createDocSetTokesFile];
+ [self createDocSetBundle];
+}
+
+//----------------------------------------------------------------------------------------
+- (void) createOutputDirectories
+{
+ // Note that we only manually create temporary documentation set directory here,
+ // if the documentation set is installed, it will be copied as a bundle to the
+ // appropriate path.
+ [Systemator createDirectory:cmd.outputDocSetPath];
+ [Systemator createDirectory:cmd.outputDocSetContentsPath];
+ [Systemator createDirectory:cmd.outputDocSetResourcesPath];
+}
+
+//----------------------------------------------------------------------------------------
+- (void) removeOutputDirectories
+{
+ // Note that we only remove temporary documentation set directory here, the installed
+ // copy is always left in it's installation directory.
+ [Systemator removeItemAtPath:cmd.outputDocSetPath];
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Documentation set handling
+//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
- (void) createDocSetSourcePlistFile
@@ -88,8 +133,8 @@ - (void) createDocSetNodesFile
logNormal(@"Creating DocSet Nodes.xml file...");
NSAutoreleasePool* loopAutoreleasePool = [[NSAutoreleasePool alloc] init];
NSXMLDocument* document = [NSXMLDocument document];
- NSString* indexFileName = [XHTMLOutputGenerator indexFileName];
- NSString* hierarchyFileName = [XHTMLOutputGenerator hierarchyFileName];
+ NSString* indexFileName = [documentationFilesInfoProvider outputIndexFilename];
+ NSString* hierarchyFileName = [documentationFilesInfoProvider outputHierarchyFilename];
// Create the version and ecoding elements.
[document setVersion:@"1.0"];
@@ -137,8 +182,7 @@ - (void) createDocSetNodesFile
for (NSDictionary* objectData in directoryObjects)
{
NSString* objectName = [objectData objectForKey:kTKDataObjectNameKey];
- NSString* objectPath = [objectData objectForKey:kTKDataObjectRelPathKey];
- objectPath = [XHTMLOutputGenerator pathByReplacingPlaceholders:objectPath];
+ NSString* objectPath = [documentationFilesInfoProvider outputObjectFilenameForObject:objectData];
NSXMLElement* objectElement = [NSXMLNode elementWithName:@"Node"];
[directorySubnodesElement addChild:objectElement];
@@ -208,8 +252,7 @@ - (void) createDocSetTokesFile
NSDictionary* objectData = [objects objectForKey:objectName];
NSXMLDocument* objectDocument = [objectData objectForKey:kTKDataObjectMarkupKey];
NSString* objectKind = [objectData objectForKey:kTKDataObjectKindKey];
- NSString* objectRelPath = [objectData objectForKey:kTKDataObjectRelPathKey];
- objectRelPath = [XHTMLOutputGenerator pathByReplacingPlaceholders:objectRelPath];
+ NSString* objectRelPath = [documentationFilesInfoProvider outputObjectFilenameForObject:objectData];
// Prepare the object identifier.
NSString* objectIdentifier = nil;
@@ -346,8 +389,7 @@ - (void) createDocSetBundle
NSString* message = [NSString stringWithFormat:@"Installation of DocSet failed with message:\n'%@'!",
[errorDict objectForKey:NSAppleScriptErrorMessage]];
logError(@"Failed installing DocSet to Xcode documentation!");
- [Systemator throwExceptionWithName:kTKConverterException
- withDescription:message];
+ [Systemator throwExceptionWithName:kTKConverterException withDescription:message];
}
[installScript release];
@@ -387,8 +429,8 @@ - (void) addDocSetNodeToElement:(NSXMLElement*) parent
NSString* objectName = [data objectForKey:kTKDataHierarchyObjectNameKey];
NSString* objectPath = [objectData objectForKey:kTKDataObjectRelPathKey];
objectPath = objectPath ?
- [XHTMLOutputGenerator pathByReplacingPlaceholders:objectPath] :
- [XHTMLOutputGenerator hierarchyFileName];
+ [documentationFilesInfoProvider outputObjectFilenameForObject:objectData] :
+ [documentationFilesInfoProvider outputHierarchyFilename];
// Create the main node that will represent the object.
NSXMLElement* node = [NSXMLNode elementWithName:@"Node"];
@@ -417,4 +459,10 @@ - (void) addDocSetNodeToElement:(NSXMLElement*) parent
}
}
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Properties
+//////////////////////////////////////////////////////////////////////////////////////////
+
+@synthesize documentationFilesInfoProvider;
+
@end
View
38 DoxygenConverter+CleanOutput.h
@@ -1,38 +0,0 @@
-//
-// DoxygenConverter+CleanOutput.h
-// appledoc
-//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#import "DoxygenConverter.h"
-
-//////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////
-/** Implements clean HTML documentation related functionality for @c DoxygenConverter
-class.
-
-This category handles conversion from clean XML files to clean HTML. It's members
-create clean HTML object and index files, and saves them in the proper directory
-structure.
-*/
-@interface DoxygenConverter (CleanOutput)
-
-//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Clean HTML handling
-//////////////////////////////////////////////////////////////////////////////////////////
-
-/** Creates cleaned XHTML documentation.
-
-This method will convert all clean XML markups in the database to XHTML files in the
-proper output directory.
-
-This message is automatically sent from @c DoxygenConverter::convert() in the proper order.
-
-@exception NSException Thrown if creation fails.
-*/
-- (void) createCleanOutputDocumentation;
-
-@end
View
74 DoxygenConverter+CleanOutput.m
@@ -1,74 +0,0 @@
-//
-// DoxygenConverter+CleanOutput.m
-// appledoc
-//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
-//
-
-#import "DoxygenConverter+CleanOutput.h"
-#import "DoxygenConverter+Helpers.h"
-#import "CommandLineParser.h"
-#import "LoggingProvider.h"
-#import "Systemator.h"
-#import "XHTMLOutputGenerator.h"
-
-@implementation DoxygenConverter (CleanOutput)
-
-//----------------------------------------------------------------------------------------
-- (void) createCleanOutputDocumentation
-{
- logNormal(@"Creating clean XHTML documentation...");
- NSAutoreleasePool* loopAutoreleasePool = nil;
-
- // Prepare the argument values.
- NSCalendarDate* now = [NSCalendarDate date];
- NSString* lastUpdatedString = [now descriptionWithCalendarFormat:@"%Y-%B-%d"];
-
- // Prepare the output generators, send them default data and notify them generation
- // is about to begin.
- XHTMLOutputGenerator* generator = [[XHTMLOutputGenerator alloc] init];
- generator.lastUpdated = lastUpdatedString;
- generator.projectName = cmd.projectName;
- [generator generationStarting];
-
- @try
- {
- // Convert the index and hierarchy files.
- [generator generateOutputForIndex:database];
- [generator generateOutputForHierarchy:database];
-
- // Convert the object files.
- NSDictionary* objects = [database objectForKey:kTKDataMainObjectsKey];
- for (NSString* objectName in objects)
- {
- [loopAutoreleasePool drain];
- loopAutoreleasePool = [[NSAutoreleasePool alloc] init];
-
- NSDictionary* objectData = [objects objectForKey:objectName];
- [generator generateOutputForObject:objectData];
- }
-
- // If cleantemp is used, remove clean XML temporary files.
- if (cmd.cleanTempFilesAfterBuild && [manager fileExistsAtPath:cmd.outputCleanXMLPath])
- {
- logInfo(@"Removing temporary clean XML files at '%@'...", cmd.outputCleanXMLPath);
- NSError* error = nil;
- if (![manager removeItemAtPath:cmd.outputCleanXMLPath error:&error])
- {
- logError(@"Failed removing temporary clean XML files at '%@'!", cmd.outputCleanXMLPath);
- [Systemator throwExceptionWithName:kTKConverterException basedOnError:error];
- }
- }
- }
- @finally
- {
- [generator generationFinished];
- [generator release];
- [loopAutoreleasePool drain];
- }
-
- logInfo(@"Finished creating clean XHTML documentation.");
-}
-
-@end
View
65 DoxygenConverter+Helpers.h
@@ -1,65 +0,0 @@
-//
-// DoxygenConverter+Helpers.h
-// appledoc
-//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-#import "DoxygenConverter.h"
-
-//////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////
-/** Defines common helper methods for @c DoxygenConverter and it's helper categories
-
-This category defines several lower level methods which are used through other conversion
-methods implemented in the main converter class or it's main categories. The main reason
-for implementing these in a separate file instead of in private category is in the fact
-that we need to link to these methods in other categories besides the main class.
-*/
-@interface DoxygenConverter (Helpers)
-
-//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Helper methods
-//////////////////////////////////////////////////////////////////////////////////////////
-
-/** Applies the XSLT from the given file to the document and returns the resulting object.
-
-This will first load the XSLT from the given file and will apply it to the document. It
-will return the transformed object which is either an @c NSXMLDocument if transformation
-created an XML or @c NSData otherwise. If transformation failed, @c nil is returned and
-error description is passed over the @c error parameter.
-
-This message internally sends @c applyXSLTFromFile:toDocument:arguments:error:() with
-arguments set to @c nil.
-
-@param filename The name of the XSLT file including full path.
-@param document The @c NSXMLDocument to transform.
-@param error If transformation failed, error is reported here.
-@return Returns transformed object or @c nil if transformation failed.
-*/
-- (id) applyXSLTFromFile:(NSString*) filename
- toDocument:(NSXMLDocument*) document
- error:(NSError**) error;
-
-/** Applies the XSLT from the given file to the document and returns the resulting object.
-
-This will first load the XSLT from the given file and will apply it to the document. It
-will return the transformed object which is either an @c NSXMLDocument if transformation
-created an XML or @c NSData otherwise. If transformation failed, @c nil is returned and
-error description is passed over the @c error parameter.
-
-@param filename The name of the XSLT file including full path.
-@param document The @c NSXMLDocument to transform.
-@param arguments An @c NSDictionary containing all arguments to be passed to the XSLT.
- May be @c nil if no argument is to be passed.
-@param error If transformation failed, error is reported here.
-@return Returns transformed object or @c nil if transformation failed.
-*/
-- (id) applyXSLTFromFile:(NSString*) filename
- toDocument:(NSXMLDocument*) document
- arguments:(NSDictionary*) arguments
- error:(NSError**) error;
-
-@end
View
40 DoxygenConverter+Helpers.m
@@ -1,40 +0,0 @@
-//
-// DoxygenConverter+Helpers.m
-// appledoc
-//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
-//
-
-#import "DoxygenConverter+Helpers.h"
-
-@implementation DoxygenConverter (Helpers)
-
-//----------------------------------------------------------------------------------------
-- (id) applyXSLTFromFile:(NSString*) filename
- toDocument:(NSXMLDocument*) document
- error:(NSError**) error
-{
- return [self applyXSLTFromFile:filename toDocument:document arguments:nil error:error];
-}
-
-//----------------------------------------------------------------------------------------
-- (id) applyXSLTFromFile:(NSString*) filename
- toDocument:(NSXMLDocument*) document
- arguments:(NSDictionary*) arguments
- error:(NSError**) error
-{
- NSString* xsltString = [NSString stringWithContentsOfFile:filename
- encoding:NSASCIIStringEncoding
- error:error];
- if (xsltString)
- {
- return [document objectByApplyingXSLTString:xsltString
- arguments:arguments
- error:error];
- }
-
- return nil;
-}
-
-@end
View
57 DoxygenConverter.h
@@ -7,40 +7,7 @@
//
#import <Foundation/Foundation.h>
-
-#define kTKConverterException @"TKConverterException"
-#define kTKPlaceholderExtension @"$EXTENSION"
-
-#define kTKDirClasses @"Classes"
-#define kTKDirCategories @"Categories"
-#define kTKDirProtocols @"Protocols"
-#define kTKDirCSS @"css"
-#define kTKDirDocSet @"docset"
-
-#define kTKDataMainIndexKey @"Index" // NSXMLDocument
-#define kTKDataMainHierarchyKey @"Hierarchy" // NSXMLDocument
-#define kTKDataMainHierarchiesKey @"Hierarchies" // NSDictionary
-#define kTKDataMainObjectsKey @"Objects" // NSDictionary
-#define kTKDataMainDirectoriesKey @"Directories" // NSDictionary
-
-#define kTKDataHierarchyObjectNameKey @"ObjectName" // NSString
-#define kTKDataHierarchyObjectDataKey @"ObjectData" // NSDictionary
-#define kTKDataHierarchyChildrenKey @"Children" // NSString
-#define kTKDataHierarchyTempKey @"TEMPORARY" // NSNumber / BOOL
-
-#define kTKDataObjectNameKey @"ObjectName" // NSString
-#define kTKDataObjectKindKey @"ObjectKind" // NSString
-#define kTKDataObjectClassKey @"ObjectClass" // NSString
-#define kTKDataObjectMarkupKey @"CleanedMarkup" // NSXMLDocument
-#define kTKDataObjectMembersKey @"Members" // NSDictionary
-#define kTKDataObjectParentKey @"Parent" // NSString
-#define kTKDataObjectRelDirectoryKey @"RelativeDirectory" // NSString
-#define kTKDataObjectRelPathKey @"RelativePath" // NSString
-#define kTKDataObjectDoxygenFilenameKey @"DoxygenMarkupFilename" // NSString
-
-#define kTKDataMemberNameKey @"Name" // NSString
-#define kTKDataMemberPrefixKey @"Prefix" // NSString
-#define kTKDataMemberSelectorKey @"Selector" // NSString
+#import "Constants.h"
@class CommandLineParser;
@@ -139,25 +106,19 @@ is a standard @c NSDictionary of the following layout:
- @c "<DirectoryName>"...
- ...
-Note that this class is closely coupled with @c CommandLineParser which it uses to
-determine the exact conversion work flow.
-
-Since this class is quite complex one, it is divided into several categories. The
-categories which implement helper methods handle individual conversion tasks. The
-helper methods are called from the main convert() method in the proper order. The
-helper categories are:
-- @c DoxygenConverter(Doxygen)
-- @c DoxygenConverter(CleanXML)
-- @c DoxygenConverter(CleanOutput)
-- @c DoxygenConverter(DocSet)
-- @c DoxygenConverter(Helpers).
+Note that this class relies on @c CommandLineParser to determine the exact conversion
+work flow and common, application-wide parameters. Internally the class delegates
+all output generation to top level @c OutputProcessing conformers which in turn manage
+all their dependent generators.
+
+This class doesn't perform any actual output generation. Instead it delegates it to the
+concrete @c OutputGenerator instances.
*/
@interface DoxygenConverter : NSObject
{
CommandLineParser* cmd;
- NSFileManager* manager;
- NSString* doxygenXMLOutputPath;
NSMutableDictionary* database;
+ NSMutableArray* topLevelGenerators;
}
//////////////////////////////////////////////////////////////////////////////////////////
View
165 DoxygenConverter.m
@@ -7,42 +7,15 @@
//
#import "DoxygenConverter.h"
+#import "Constants.h"
#import "Systemator.h"
#import "LoggingProvider.h"
#import "CommandLineParser.h"
-#import "DoxygenConverter+Doxygen.h"
-#import "DoxygenConverter+CleanXML.h"
-#import "DoxygenConverter+CleanOutput.h"
-#import "DoxygenConverter+DocSet.h"
-#import "DoxygenConverter+Helpers.h"
-
-//////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////
-/** Declares methods private for the @c DoxygenConverter class.
-*/
-@interface DoxygenConverter (ClassPrivateAPI)
-
-/** Creates all required output directories and optionally removes all existing files.
-
-This makes sure file renames and deletes are properly handled - doxygen doesn't delete
-these. This actually doesn't present any problem if html output is used, because obsolete
-files are simply not linked once the index.html is opened even though the files are
-present on the output path. However in case of xml output, this would result in obsolete
-files still being handled by the utility.
-
-Note that the files are only removed if the remove option was used in command line.
-This option should only be used if the output is generated in the special directory.
-If the output is created in the same directory as the project source files (should
-really not!), this will alse remove all source files, so be careful!
-
-This message is automaticaly sent from @c DoxygenConverter::convert() in the proper order.
-
-@exception NSException Thrown if cleaning fails.
-*/
-- (void) createOutputDirectoriesAndRemovePreviousOutputFiles;
-
-@end
+#import "DoxygenOutputGenerator.h"
+#import "XMLOutputGenerator.h"
+#import "XHTMLOutputGenerator.h"
+#import "DocSetOutputGenerator.h"
@implementation DoxygenConverter
@@ -56,7 +29,30 @@ - (id)init
self = [super init];
if (self)
{
+ cmd = [CommandLineParser sharedInstance];
database = [[NSMutableDictionary alloc] init];
+
+ // Setup all output generators.
+ DoxygenOutputGenerator* doxygenGenerator = [[DoxygenOutputGenerator alloc] initWithDatabase:database];
+ XMLOutputGenerator* xmlGenerator = [[XMLOutputGenerator alloc] initWithDatabase:database];
+ XHTMLOutputGenerator* xhtmlGenerator = [[XHTMLOutputGenerator alloc] initWithDatabase:database];
+ DocSetOutputGenerator* docSetGenerator = [[DocSetOutputGenerator alloc] initWithDatabase:database];
+
+ // Setup all dependencies.
+ [doxygenGenerator registerDependentGenerator:xmlGenerator];
+ [xmlGenerator registerDependentGenerator:xhtmlGenerator];
+ [xhtmlGenerator registerDependentGenerator:docSetGenerator];
+ docSetGenerator.documentationFilesInfoProvider = xhtmlGenerator;
+
+ // Setup top level generators.
+ topLevelGenerators = [[NSMutableArray alloc] init];
+ [topLevelGenerators addObject:doxygenGenerator];
+
+ // We can now release generators because they are retained by their parents.
+ [doxygenGenerator release];
+ [xmlGenerator release];
+ [xhtmlGenerator release];
+ [docSetGenerator release];
}
return self;
}
@@ -64,8 +60,9 @@ - (id)init
//----------------------------------------------------------------------------------------
- (void) dealloc
{
- [doxygenXMLOutputPath release], doxygenXMLOutputPath = nil;
+ cmd = nil;
[database release], database = nil;
+ [topLevelGenerators release], topLevelGenerators = nil;
[super dealloc];
}
@@ -78,94 +75,44 @@ - (void) convert
{
logNormal(@"Creating documentation...");
- // Prepare common data for the whole run so that the code will be simpler.
- cmd = [CommandLineParser sharedInstance];
- manager = [NSFileManager defaultManager];
+ NSFileManager* manager = [NSFileManager defaultManager];
+ // If required, remove output directory to get a fresh start.
+ if (cmd.cleanOutputFilesBeforeBuild && [manager fileExistsAtPath:cmd.outputPath])
+ {
+ logNormal(@"Removing previous output files...");
+ [Systemator removeItemAtPath:cmd.outputPath];
+ logInfo(@"Finished removing previous output files.");
+ }
+
+ // If output directory doesn't yet exist, create it.
+ if (![manager fileExistsAtPath:cmd.outputPath])
+ {
+ logNormal(@"Creating output path...");
+ [Systemator createDirectory:cmd.outputPath];
+ logInfo(@"Finished creating output path.");
+ }
+
// Clear common variables.
[database removeAllObjects];
[database setObject:[NSMutableDictionary dictionary] forKey:kTKDataMainObjectsKey];
[database setObject:[NSMutableDictionary dictionary] forKey:kTKDataMainHierarchiesKey];
[database setObject:[NSMutableDictionary dictionary] forKey:kTKDataMainDirectoriesKey];
- [doxygenXMLOutputPath release], doxygenXMLOutputPath = [[cmd outputPath] retain];
-
- // Run all the tasks.
- [self createOutputDirectoriesAndRemovePreviousOutputFiles];
-
- [self createDoxygenConfigFile];
- [self updateDoxygenConfigFile];
- [self createDoxygenDocumentation];
-
- [self createCleanObjectDocumentationMarkup];
- [self mergeCleanCategoriesToKnownObjects];
- [self updateCleanObjectsDatabase];
- [self createCleanIndexDocumentationFile];
- [self createCleanHierarchyDocumentationFile];
- [self fixCleanObjectDocumentation];
- [self saveCleanObjectDocumentationFiles];
-
- [self createCleanOutputDocumentation];
- if (cmd.createDocSet)
- {
- [self createDocSetSourcePlistFile];
- [self createDocSetNodesFile];
- [self createDocSetTokesFile];
- [self createDocSetBundle];
- }
- logNormal(@"Succesfully finished documentation creation.");
-}
-
-//////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Common tasks
-//////////////////////////////////////////////////////////////////////////////////////////
-
-//----------------------------------------------------------------------------------------
-- (void) createOutputDirectoriesAndRemovePreviousOutputFiles
-{
- NSError* error = nil;
-
- // If required, remove current directory to get a fresh start.
- if (cmd.cleanOutputFilesBeforeBuild && [manager fileExistsAtPath:cmd.outputPath])
+ // Create all top level outputs. Note that this will in turn start all their
+ // dependent output generations.
+ logNormal(@"Generating output documentation...");
+ for (id<OutputProcessing> topLevelGenerator in topLevelGenerators)
{
- logNormal(@"Removing previous output files at '%@'...", cmd.outputPath);
-
- // Remove previous directory.
- if (![manager removeItemAtPath:cmd.outputPath error:&error])
+ if (topLevelGenerator.isOutputGenerationEnabled)
{
- logError(@"Failed removing previous output files at '%@'!", cmd.outputPath);
- [Systemator throwExceptionWithName:kTKConverterException basedOnError:error];
+ [topLevelGenerator generateOutput];
}
-
- logInfo(@"Finished removing previous output files.");
}
+ logInfo(@"Finished generating output documentation.");
- // If the output directories don't exist, create them now. Note that for DocSet we
- // create all different directories. Since they are nested we could only create the
- // deepest one. However using this "non-smart" approach is safer in possible future
- // cases where the directory structure might change. Also note that the documents
- // directory is not created here. This will make it easier to copy the html later on...
- logNormal(@"Creating output directories at '%@'...", cmd.outputPath);
- [Systemator createDirectory:cmd.outputPath];
- [Systemator createDirectory:cmd.outputCleanXMLPath];
- [Systemator createDirectory:[cmd.outputCleanXMLPath stringByAppendingPathComponent:kTKDirClasses]];
- [Systemator createDirectory:[cmd.outputCleanXMLPath stringByAppendingPathComponent:kTKDirCategories]];
- [Systemator createDirectory:[cmd.outputCleanXMLPath stringByAppendingPathComponent:kTKDirProtocols]];
- if (cmd.createCleanXHTML)
- {
- [Systemator createDirectory:cmd.outputCleanXHTMLPath];
- [Systemator createDirectory:[cmd.outputCleanXHTMLPath stringByAppendingPathComponent:kTKDirClasses]];
- [Systemator createDirectory:[cmd.outputCleanXHTMLPath stringByAppendingPathComponent:kTKDirCategories]];
- [Systemator createDirectory:[cmd.outputCleanXHTMLPath stringByAppendingPathComponent:kTKDirProtocols]];
- [Systemator createDirectory:[cmd.outputCleanXHTMLPath stringByAppendingPathComponent:kTKDirCSS]];
- }
- if (cmd.createDocSet)
- {
- [Systemator createDirectory:cmd.outputDocSetPath];
- [Systemator createDirectory:cmd.outputDocSetContentsPath];
- [Systemator createDirectory:cmd.outputDocSetResourcesPath];
- }
- logInfo(@"Finished creating output directories.");
+ // Notify the users that creation was succesful.ß
+ logNormal(@"Succesfully created output documentation.");
}
@end
View
48 DoxygenConverter+Doxygen.h → DoxygenOutputGenerator.h
@@ -1,22 +1,25 @@
//
-// DoxygenConverter+Doxygen.h
+// DoxygenOutputGenerator.h
// appledoc
//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
+// Created by Tomaz Kragelj on 11.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
//
-#import <Foundation/Foundation.h>
-#import "DoxygenConverter.h"
+#import "OutputGenerator.h"
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
-/** Implemented doxygen related functionality for @c DoxygenConverter class.
-
-This category handles doxygen configuration file creation, updating default parameters
-with user specified ones and running the doxygen utility itself.
+/** Defines a concrete @c OutputGenerator which runs doxygen over the source files to
+generate intermediate XML documentation.
+
+The generator first checks if required doxygen configuration file exists. If not, it
+creates it and updates it so that default options are all set. Then it extracts the
+actual XML output directory path and other relevant values which can be changed by
+the user after initial creation. When doxygen configuration file is processed, the
+generator invokes doxygen so that it actually generates the output for us.
*/
-@interface DoxygenConverter (Doxygen)
+@interface DoxygenOutputGenerator : OutputGenerator
//////////////////////////////////////////////////////////////////////////////////////////
/// @name Doxygen handling
@@ -24,12 +27,14 @@ with user specified ones and running the doxygen utility itself.
/** Creates the doxygen configuration file if it doesn't exist yet.
-This method will check if the desired doxygen file already exists or not. If not, it will
-create it by asking doxygen itself to generate the default file. Then it will change all
-options as necessary.
+This method checks if the desired doxygen file already exists or not. If not, it creates
+it by asking doxygen itself to generate the default file including comments so that later
+manual tweaking is easier. Then it changes the default options so that XML output is
+generated only. If the configuration file already exists, nothing happens.
+
+This message is automatically sent from @c generateSpecificOutput() in the proper order.
+It is not designed to be sent manually from the clients.
-This message is automaticaly sent from @c DoxygenConverter::convert() in the proper order.
-
@exception NSException Thrown if creation of the file fails.
@see updateDoxygenConfigFile
@see createDoxygenDocumentation
@@ -42,11 +47,13 @@ This method will check if configuration file exists or not. If it does, it will
and replace default options with new ones. If it finds at least one option changed,
it will not update the file to preserve any user customizations.
-Note that this method will also remember the xml output path, so that we can use it
+Note that this method will also parse the actual xml output path from the configuration
+file and will set to the @c CommandLineParser, so that other generators can use it
later on.
-This message is automaticaly sent from @c DoxygenConverter::convert() in the proper order.
-
+This message is automatically sent from @c generateSpecificOutput() in the proper order.
+It is not designed to be sent manually from the clients.
+
@exception NSException Thrown if doxygen configuration file doesn't exist or cannot be
parsed or changed.
@see createDoxygenConfigFile
@@ -60,8 +67,9 @@ This method will check if configuration file exists or not. If it does, it will
doxygen so that documentation is created. If the file doesn't exist, an exception will
be thrown.
-This message is automaticaly sent from @c DoxygenConverter::convert() in the proper order.
-
+This message is automatically sent from @c generateSpecificOutput() in the proper order.
+It is not designed to be sent manually from the clients.
+
@exception NSException Thrown if doxygen configuration file doesn't exist or documentation
creation fails (probably due to corrupted or invalid file).
@see createDoxygenConfigFile
View
40 DoxygenConverter+Doxygen.m → DoxygenOutputGenerator.m
@@ -1,17 +1,21 @@
//
-// DoxygenConverter+Doxygen.m
+// DoxygenOutputGenerator.m
// appledoc
//
-// Created by Tomaz Kragelj on 17.4.09.
-// Copyright 2009 Tomaz Kragelj. All rights reserved.
+// Created by Tomaz Kragelj on 11.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
//
-#import "DoxygenConverter+Doxygen.h"
+#import "DoxygenOutputGenerator.h"
#import "CommandLineParser.h"
#import "LoggingProvider.h"
#import "Systemator.h"
-@implementation DoxygenConverter (Doxygen)
+@implementation DoxygenOutputGenerator
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Doxygen handling
+//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
- (void) createDoxygenConfigFile
@@ -174,8 +178,8 @@ - (void) updateDoxygenConfigFile
// Remember XML output path.
if ([optionName rangeOfString:@"XML_OUTPUT"].location != NSNotFound)
{
- doxygenXMLOutputPath = [[[cmd outputPath] stringByAppendingPathComponent:optionValue] retain];
- logInfo(@"Found XML_OUTPUT set to %@.", doxygenXMLOutputPath);
+ cmd.outputDoxygenXMLPath = [[[cmd outputPath] stringByAppendingPathComponent:optionValue] retain];
+ logInfo(@"Found XML_OUTPUT set to %@.", cmd.outputDoxygenXMLPath);
}
}
}
@@ -209,4 +213,26 @@ - (void) createDoxygenDocumentation
logInfo(@"Finished creating doxygen documentation.");
}
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Specific output generation entry points
+//////////////////////////////////////////////////////////////////////////////////////////
+
+//----------------------------------------------------------------------------------------
+- (void) generateSpecificOutput
+{
+ [self createDoxygenConfigFile];
+ [self updateDoxygenConfigFile];
+ [self createDoxygenDocumentation];
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Specific output directories handling
+//////////////////////////////////////////////////////////////////////////////////////////
+
+//----------------------------------------------------------------------------------------
+- (void) removeOutputDirectories
+{
+ [Systemator removeItemAtPath:cmd.outputDoxygenXMLPath];
+}
+
@end
View
397 OutputGenerator.h
@@ -2,328 +2,191 @@
// OutputGenerator.h
// appledoc
//
-// Created by Tomaz Kragelj on 28.5.09.
+// Created by Tomaz Kragelj on 11.6.09.
// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
//
#import <Foundation/Foundation.h>
+#import "OutputProcessing.h"
+#import "OutputInfoProvider.h"
+#import "Constants.h"
@class CommandLineParser;
-/** Defines different object info item types. */
-enum TKGeneratorObjectInfoItemTypes
-{
- kTKObjectInfoItemInherits,
- kTKObjectInfoItemConforms,
- kTKObjectInfoItemDeclared,
-};
-
-/** Defines different object main member group types. */
-enum TKGeneratorObjectMemberTypes
-{
- kTKObjectMemberTypeClass,
- kTKObjectMemberTypeInstance,
- kTKObjectMemberTypeProperty,
-};
-
-/** Defines different object member prototype item types. These values define the type
-of the item which can either be value or parameter name. */
-enum TKGeneratorObjectPrototypeTypes
-{
- kTKObjectMemberPrototypeValue,
- kTKObjectMemberPrototypeParameter,
-};
-
-/** Defines different object common member section types. These are used mainly to
-simplify the code and avoid repetition since many member sections use the same layout
-for different types of sections. */
-enum TKGeneratorObjectMemberSectionTypes
-{
- kTKObjectMemberSectionParameters,
- kTKObjectMemberSectionExceptions,
-};
-
-/** Defines different index group types. These are used mainly to simplify the code and
- avoid repetition since all of the groups use the same layout. */
-enum TKGeneratorIndexGroupTypes
-{
- kTKIndexGroupClasses,
- kTKIndexGroupProtocols,
- kTKIndexGroupCategories,
-};
-
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
/** Defines the basics for an output generator.
-Output generators are objects that generate final output files from the intermediate
-(cleaned) XML. Each type of supported output is implemented by a concrete subclass.
-This class should be treated as abstract base class. It provides the stubs for the
-output generation as well as several helper methods that the subclasses can use to
-make their job easier.
+Output generators are objects that generate final output from intermediate files. Each
+type of supported output is implemented by a concrete subclass. This class should be
+treated as abstract base class. It provides the stubs for the output generation which
+should be overriden by subclasses to implement the required functionality. Output
+generators conform to @c OutputProcessing and @c OutputInfoProvider formal protocols.
+The @c OutputProcessing protocol is fully implemented, however the subclasses need to
+override @c OutputInfoProvider::outputFilesExtension() and return proper value. Default
+implementation returns empty string. The rest of the @c OutputInfoProvider methods should
+generally be correctly implemented by the base class though.
-Each concrete subclass can convert three types of files - index, hierarchy and object files.
-The subclass can only override the methods for generating output that makes sense for the
-implemented output type. The clients send @c generateOutputForIndex:() to generate the
-main index file, @c generateOutputForHierarchy:() to generate the main hierarchy
-file and @c generateOutputForObject:() to generate the documentation for
-individual objects.
+Additionally, output generators also support tree-like generation of dependent generators.
+This allows simple handling of dependent generation and eliminates the worry of when to
+start certain dependent generator, when to remove temporary files etc. Dependent
+generators must be registered prior than starting the actual generation. Registration is
+performed by sending the receiver @c registerDependentGenerator:() message. Note that
+clients are responsible for setting up dependencies, @c OutputGenerator objects then
+handle all dependent generators at proper time.
-In all cases, there are two options for generating output in the subclass. The first is
-to use the default stubs. This means that the subclass should leave the layout and order
-of creation to the base class and should override several methods which are sent during
-the creation, depending the object that is being generated. The methods which fall into
-this category are easily identified by their @c append prefix. This is the most common
-and also the simplest way of getting the job done. However it limits the order in which
-output elements are generated (of course the subclass can still use this way and generate
-intermediate results which it can store to class variables and then use to generate the
-complete output at the end of appending). If the subclass requires more control, it can
-also override @c outputDataForObject(), @c outputDataForIndex() and/or
-@c outputDataForHierarchy() methods and handle the data in a completely custom way
-(@c outputDataForObject() message is sent from @c generateOutputForObject:() which
-sets the class properties with the object data, so the subclass can use these to make
-it's life easier. Similarly, @c outputDataForIndex() is sent from @c generateOutputForIndex:()
-and @c outputDataForHierarchy() from @c generateOutputForHierarchy:()).
+@c OutputGenerator is an abstract base class. Concrete subclasses should implement their
+specifics within the following overrides:
+- @c outputGenerationStarting()
+- @c outputGenerationFinished()
+- @c generateSpecificOutput(): concrete subclasses should override this method and
+ generate their specific output based on their promise. This message is sent from
+ @c generateOutput() which takes care of handling dependencies and directories
+ creation and removal among other things. So in general, subclasses should not
+ override @c generateOutput().
+- @c createOutputDirectories()
+- @c removeOutputDirectories()
-The class is designed so that the same instance can be re-used for generation of several
-objects by simply sending the instance @c generateOutputForObject:() message,
-@c generateOutputForIndex:() and/or @c generateOutputForHierarchy:() with
-the required data.
+Note that the @c OutputGenerator base class provides some helper variables to prevent
+repetition and allow less cluttered code in the concrete subclasses. These include:
+- @c manager: Set to the @c NSFileManager::defaultManager().
+- @c cmd: Set to the @c CommandLineParser::sharedInstance().
+- @c database: Set to the main objects database (set through the @c initWithDatabase:).
*/
-@interface OutputGenerator : NSObject
+@interface OutputGenerator : NSObject <OutputProcessing, OutputInfoProvider>
{
CommandLineParser* cmd;
- NSDictionary* objectData;
- NSDictionary* indexData;
- NSDictionary* hierarchyData;
- NSXMLDocument* objectMarkup;
- NSXMLDocument* indexMarkup;
- NSXMLDocument* hierarchyMarkup;
- NSString* projectName;
- NSString* lastUpdated;
- BOOL wasFileCreated;
+ NSFileManager* manager;
+ NSMutableDictionary* database;
+ NSMutableArray* dependentGenerators;
}
//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Generation entry points
+/// @name Initialization & disposal
//////////////////////////////////////////////////////////////////////////////////////////
-/** Generates the output data from the given object data.
+/** Initializes the output generator.
-This is the main message that starts the whole generation for the given object. It copies
-the values from the given data to the properties and then sends the receiver
-@c outputDataForObject() message that triggers the object data parsing and in turn sends
-the receiver several messages that can be used to convert the data. When conversion
-finishes, the data is saved to the given file.
+This is the designated initializer. It maps the main objects database so it is accessible
+for subclasses.
-@param data An @c NSDictionary that describes the object for which output is generated.
-@exception NSException Thrown if the given @c data or saving to file fails.
-@see outputDataForObject
-@see generateOutputForIndex:
-@see generateOutputForHierarchy:
+@param data The main database of objects which is used for creating output. The value is
+ retained by the initializer, so all instances should be released when no longer used.
+@return Returns initialized object or @c nil if initialization fails.
+@exception NSException Thrown if the given database is @c nil or initialization fails.
+@warning @b Important: Note that the some concrete subclasses actually create the data
+ in the database, while others only use it. Therefore it is important that the
+ generation is invoked in the proper order. This is one of the points where clients
+ should be aware of the proper order of creation and how different output generator
+ subclasses are linked together.
*/
-- (void) generateOutputForObject:(NSDictionary*) data;
+- (id) initWithDatabase:(NSMutableDictionary*) data;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+/// @name Dependencies handling
+//////////////////////////////////////////////////////////////////////////////////////////
-/** Generates the output data from the given index data.
+/** Registers the given dependent generator and adds it to the end of the dependent
+generators list.
-This is the main message that starts the whole generation for the given index. It copies
-the values from the given data to the properties and then sends the receiver
-@c outputDataForIndex() message that triggers the object data parsing and in turn sends
-the receiver several messages that can be used to convert the data. When conversion
-finishes, the data is saved to the given file.
+After dependent generator is registered, it is automaticallty handled, so clients don't
+have to manually invoke it's output generation. Furthermore, removal of temporary files
+is also automatically handled at proper time. Note that the given generator may in turn
+have more dependent generators registered - output generation recursively invokes
+generation in proper order. At this point, generators cannot be unregistered!
+
+Note that all dependent generators must be registered before generating the output for
+the receiver (i.e. before sending @c generateOutput() message).
-@param data The main database @c NSDictionary that describes all objects and data.
-@exception NSException Thrown if the given @c data or saving to file fails.
-@see outputDataForIndex
-@see generateOutputForObject:
-@see generateOutputForHierarchy:
+@param generator The @c OutputProcessing subclass which depends on this generator.
+@exception NSException Thrown if the given @c generator is @c nil.
*/
-- (void) generateOutputForIndex:(NSDictionary*) data;
+- (void) registerDependentGenerator:(id<OutputProcessing>) generator;
-/** Generates the output data from the given hierarchy data.
-
-This is the main message that starts the whole generation for the given hierarchy. It
-copies the values from the given data to the properties and then sends the receiver
-@c outputDataForHierarchy() message that triggers the object data parsing and in turn sends
-the receiver several messages that can be used to convert the data. When conversion
-finishes, the data is saved to the given file.
+//////////////////////////////////////////////////////////////////////////////////////////
+/// @name Output generation entry points
+//////////////////////////////////////////////////////////////////////////////////////////
-@param data The main database @c NSDictionary that describes all objects and data.
-@exception NSException Thrown if the given @c data or saving to file fails.
-@see outputDataForHierarchy
-@see generateOutputForObject:
-@see generateOutputForIndex:
+/** Notifies output generator that generation is starting.
+
+This message is sent after previous output generator finishes but before the concrete
+output generator starts processing the data. Subclasss can use it to setup initial
+values if for example. When the receiver returns from the method, @c generateOutput()
+is sent, followed by @c outputGenerationFinished().
+
+@warning @c Important: Note that implementors
+@see outputGenerationFinished
+@see generateSpecificOutput
*/
-- (void) generateOutputForHierarchy:(NSDictionary*) data;
+- (void) outputGenerationStarting;
-/** Indicates that the output generation is starting.
+/** Notifies output generator that generation is finished.
-This message is sent by the clients before any generation is started. It allows subclasses
-to performs any custom "global" prerequisites handling such as copying templates to known
-locations or similar tasks.
+This message is sent after the concrete output generator processing ends but before
+next generator starts processing the data. Subclasss can use it to cleanup after
+processing or to perform final tasks which depend on the processing results.
-@see generationFinished
-@warning If the subclass overrides this method, it must call base implementation, or
- manually reset @c wasFileCreated(), otherwise it will not show proper value.
+@exception NSException Thrown if errors are detected while finalizing output generation.
+@see outputGenerationStarting
+@see generateSpecificOutput
*/
-- (void) generationStarting;
+- (void) outputGenerationFinished;
-/** Indicates that the output generation has finished.
+/** Notifies concrete output generator subclass to start processing the data and
+generate output.
-This message is sent by the clients after generation of all files is finished. It allows
-the subclasses to perform any custom "global" handling such as copying stylesheets or
-other similar tasks.
-
-The subclass can use @c wasFileCreated() property value to determine if any file was
-indeed created.
-
-@see generationStarting
+This message is sent after @c createOutputDirectories() and @c outputGenerationStarting().
+The concrete subclass should only handle it's specific output generation. After the
+subclass returns, @c outputGenerationFinished() is sent. If any dependent generator is
+assigned, their output generation is issued afterwards. And when all dependent generators
+finish, @c removeOutputDirectories() is sent if temporary files should be removed.
+
+@exception NSException Thrown if output generation fails.
+@see outputGenerationStarting
+@see outputGenerationFinished
*/
-- (void) generationFinished;
+- (void) generateSpecificOutput;
//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Subclass output generation
+/// @name Output directories handling
//////////////////////////////////////////////////////////////////////////////////////////
-/** Generates the output data from the data contained in the class properties.
-
-This message is sent from @c generateOutputForObject:() after the passed object data
-is stored in the class properties. The concrete subclasses that require full control over
-the generated data, can override this method and return the desired output. If overriden,
-the subclass can get the XML document through the @c objectMarkup property.
-
-By default, this will send several higher level messages which can be overriden instead.
-The messages are sent in the following order:
-- @c appendObjectHeaderToData:()
-- @c appendObjectInfoHeaderToData:() @a *
-- @c appendObjectInfoItemToData:fromItems:index:type:() @a **
-- @c appendObjectInfoFooterToData:() @a *
-- @c appendObjectOverviewToData:fromItem:() @a *
-- @c appendObjectTasksHeaderToData:() @a *
-- @c appendObjectTaskHeaderToData:fromItem:index:() @a **
-- @c appendObjectTaskMemberToData:fromItem:index:() @a **
-- @c appendObjectTaskFooterToData:fromItem:index:() @a **
-- @c appendObjectTasksFooterToData:() @a *
-- @c appendObjectMembersHeaderToData:() @a *
-- @c appendObjectMemberGroupHeaderToData:type:() @a **
-- @c appendObjectMemberToData:fromItem:index:() @a **
-- @c appendObjectMemberGroupFooterToData:type:() @a **
-- @c appendObjectMembersFooterToData:() @a *
-- @c appendObjectFooterToData:()
-
-Note that only a subset of above messages may be sent for a particular object, depending
-on the object data. Messages marked with @a * are optional, while messages marked with
-@a ** may additionaly be sent multiple times, for each corresponding item once.
-
-@return Returns an autoreleased @c NSData containing generated output.
-@exception NSException Thrown if generation fails.
-@see generateOutputForObject:
-@see outputDataForIndex
-@see outputDataForHierarchy
-*/
-- (NSData*) outputDataForObject;
+/** Creates all required output directories.
-/** Generates the output data from the data contained in the class properties.
+This message is sent before any output generation begins if the subclass returns @ YES
+from @c isOutputGenerationEnabled(). Subclasses should create all directories they require.
+If any of the required directories already exists, the subclass should decide on whether
+it should delete it or skip it. In most cases, the directory is left as is. If the directory
+contains files, the subclass should again decide whether it should remove these or
+leave them. Again, in most cases the files can be left as they are.
-This message is sent from @c generateOutputForIndex:() after the passed object data
-is stored in the class properties. The concrete subclasses that require full control over
-the generated data, can override this method and return the desired output. If overriden,
-the subclass can get the database @c NSDictionary data through the @c indexMarkup() property.
-
-By default, this will send several higher level messages which can be overriden instead.
-The messages are sent in the following order:
-- @c appendIndexHeaderToData:()
-- @c appendIndexGroupHeaderToData:type:() **
-- @c appendIndexGroupItemToData:fromItem:index:type:() **
-- @c appendIndexGroupFooterToData:type:() **
-- @c appendIndexFooterToData:()
-
-Note that only a subset of above messages may be sent for a particular object, depending
-on the object data. Messages marked with @a * are optional, while messages marked with
-@a ** may additionaly be sent multiple times, for each corresponding item once.
-
-@return Returns an autoreleased @c NSData containing generated output.
-@exception NSException Thrown if generation fails.
-@see generateOutputForIndex:
-@see outputDataForObject
-@see outputDataForHierarchy
+@exception NSException Thrown if directories creation fails.
+@see removeOutputDirectories
*/
-- (NSData*) outputDataForIndex;
+- (void) createOutputDirectories;
-/** Generates the output data from the data contained in the class properties.
+/** Removes all output directories and files.
-This message is sent from @c generateOutputForHierarchy:() after the passed object
-data is stored in the class properties. The concrete subclasses that require full control
-over the generated data, can override this method and return the desired output. If
-overriden, the subclass can get the database @c NSDictionary data through the
-@c hierarchyMarkup() property.
-
-By default, this will send several higher level messages which can be overriden instead.
-The messages are sent in the following order:
-- @c appendHierarchyHeaderToData:()
-- @c appendHierarchyGroupHeaderToData:() **
-- @c appendHierarchyGroupItemToData:fromItem:index:() **
-- @c appendHierarchyGroupFooterToData:() **
-- @c appendHierarchyFooterToData:()
-
-Note that only a subset of above messages may be sent for a particular object, depending
-on the object data. Messages marked with @a * are optional, while messages marked with
-@a ** may additionaly be sent multiple times, for each corresponding item once.
-
-@return Returns an autoreleased @c NSData containing generated output.
-@exception NSException Thrown if generation fails.
-@warning @b Important: Since objects hierarchy is tree-like structure with multiple levels,
- subclass should be able to have full control of when the children of a particular item
- are handled. The base class only automates the root objects notifications, while the
- subclass is responsible for sending @c generateHierarchyGroupChildrenToData:forItem:()
- from within it's @c appendHierarchyGroupItemToData:fromItem:index:() override in order
- to trigger the parsing of the children (if there are some). This deviates somehow from
- the rest of the output generation types.
-@warning @b Note: The above mentioned deviation actually starts recursive loop between
- @c generateHierarchyGroupChildrenToData:forItem:() and
- @c appendHierarchyGroupItemToData:fromItem:index:(), however do not fear, since the
- base class method will automatically stop when no more children are detected.
-@see generateOutputForHierarchy:
-@see outputDataForObject
-@see outputDataForIndex
-*/
-- (NSData*) outputDataForHierarchy;
-
-/** Returns the output files extension.
+This message is sent after all concrete output generators finish their jobs if temporary
+files should be removed or before generation starts if clean run is desired. Subclasses
+should remove all generated directories and files. Note that this message is only sent
+if @c createOutputDirectories() was sent at the start of the generation.
-Subclasses must override this and return proper files extension. Default implementation
-throws an exception in case the subclass would forget to override.
-
-@return Returns the extension to use for the file, including the dot char.
-@exception NSException Thrown from the base class implementation.
+@exception NSException Thrown if removing directories or files fails.
+@see createOutputDirectories
*/
-- (NSString*) outputFilesExtension;
+- (void) removeOutputDirectories;
//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Properties
+/// @name Helper methods
//////////////////////////////////////////////////////////////////////////////////////////
-/** Sets or returns the project name.
-
-Clients should set this value prior to sending @c generateOutputForObject:() or
-@c generateOutputForIndex:() messages. If the value is non @c nil and is not an empty
-string, the value can be used by the concrete generators to indicate the project name.
-*/
-@property(copy) NSString* projectName;
-
-/** Sets or returns the last updated date.
+/** Creates a new @c NSString by replacing path placeholders in the given template path.
-Clients should set this value prior to sending @c generateOutputForObject:() or
-@c generateOutputForIndex:() messages. If the value is non @c nil and is not an empty,
-the value can be used by the concrete generators to indicate the time of the last update.
+@param path The template path in which to replace placeholders.
+@return Returns an autoreleased @c NSString containing correct path.
*/
-@property(copy) NSString* lastUpdated;
+- (NSString*) pathByReplacingTemplatePlaceholdersInPath:(NSString*) path;
-/** Returns the status of output files generation.
-
-This returns @c YES if at least one output file was generated within the last generation
-run (i.e. between the @c generationStarting() and @c generationFinished() messages).
-*/
-@property(readonly) BOOL wasFileCreated;
-@end
+@end
View
626 OutputGenerator.m
@@ -2,224 +2,29 @@
// OutputGenerator.m
// appledoc
//
-// Created by Tomaz Kragelj on 28.5.09.
+// Created by Tomaz Kragelj on 11.6.09.
// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
//
#import "OutputGenerator.h"
-#import "OutputGenerator+GeneralParsingAPI.h"
-#import "OutputGenerator+ObjectParsingAPI.h"
-#import "OutputGenerator+ObjectSubclassAPI.h"
-#import "OutputGenerator+IndexParsingAPI.h"
-#import "OutputGenerator+IndexSubclassAPI.h"
-#import "OutputGenerator+HierarchyParsingAPI.h"
-#import "OutputGenerator+HierarchySubclassAPI.h"
#import "CommandLineParser.h"
-#import "DoxygenConverter.h"
-#import "LoggingProvider.h"
-#import "Systemator.h"
-
-//////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////
-/** Defines private methods for use within @c OutputGenerator class only.
-
-These are helper methods to make the main @c generateOutput() less cluttered. The methods
-should only be used internaly by the @c OutputGenerator, they are not intended to be used
-by the subclasses. Therefore the parameters are closely coupled to the underlying clean
-object markup which is XML.
-*/
-@interface OutputGenerator ()
-
-//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Object generation helpers
-//////////////////////////////////////////////////////////////////////////////////////////
-
-/** Generates the object info section if necessary.
-
-From here the following messages are sent to the subclass:
-- @c appendObjectInfoHeaderToData:()
-- @c appendObjectInfoFooterToData:()
-
-@param data The @c NSMutableData to append to.
-@exception NSException Thrown if generation fails.
-@see generateOutputForObject
-@see generateOverviewSectionToData:
-@see generateTasksSectionToData:
-@see generateObjectMembersSectionToData:
-@see generateObjectInfoSectionToData:fromNodes:index:type:
-*/
-- (void) generateObjectInfoSectionToData:(NSMutableData*) data;
-
-/** Generates the given object info section if necessary.
-
-This is sent from @c generateObjectInfoSectionToData:() for each info section item. From here
-the following message is sent to the subclass.
-- @c appendObjectInfoItemToData:fromItems:index:type:()
-
-The message is only send if the given @c nodes array is not empty. The @c type parameter
-can be one of the following:
-- @c kTKObjectInfoItemInherits: The @c nodes contain inherit from information.
-- @c kTKObjectInfoItemConforms: The @c nodes contain conforms to information.
-- @c kTKObjectInfoItemDeclared: The @c nodex contain declared in information.
-
-@param data The @c NSMutableData to append to.
-@param nodes The array of @c NSXMLElement instances to append to.
-@param index Pointer to zero based index of the section item. The method will increment
- if the given @c nodes is not empty.
-@param type Type of the section item.
-@exception NSException Thrown if generation fails.
-@see generateObjectInfoSectionToData:
-*/
-- (void) generateObjectInfoSectionToData:(NSMutableData*) data
- fromNodes:(NSArray*) nodes
- index:(int*) index
- type:(int) type;
-
-/** Generates the object overview data if necessary.
-
-This is where the following messages are sent to the subclass:
-- @c appendObjectOverviewToData:fromItem:()
-
-@param data The @c NSMutableData to append to.
-@exception NSException Thrown if generation fails.
-@see generateOutputForObject
-@see generateObjectInfoSectionToData:
-@see generateTasksSectionToData:
-@see generateObjectMembersSectionToData:
-*/
-- (void) generateObjectOverviewSectionToData:(NSMutableData*) data;
-
-/** Generates the tasks section data if necessary.
-
-This is where the following messages are sent to the subclass:
-- @c appendObjectTasksHeaderToData:()
-- @c appendObjectTaskHeaderToData:fromItem:index:()
-- @c appendObjectTaskMemberToData:fromItem:index:()
-- @c appendObjectTaskFooterToData:fromItem:index:()
-- @c appendObjectTasksFooterToData:()
-
-@param data The @c NSMutableData to append to.
-@exception NSException Thrown if generation fails.
-@see generateOutputForObject
-@see generateObjectInfoSectionToData:
-@see generateOverviewSectionToData:
-@see generateObjectMembersSectionToData:
-*/
-- (void) generateObjectTasksSectionToData:(NSMutableData*) data;
-
-/** Generates the main members documentation section if necessary.
-
-This is where the following messages are sent to the subclass:
-- @c appendObjectMembersHeaderToData:()
-- @c appendObjectMembersFooterToData:()
-
-@param data The @c NSMutableData to append to.
-@exception NSException Thrown if generation fails.
-@see generateOutputForObject
-@see generateObjectInfoSectionToData:
-@see generateOverviewSectionToData:
-@see generateTasksSectionToData:
-@see generateMemberSectionToData:fromItems:type:
-*/
-- (void) generateObjectMembersSectionToData:(NSMutableData*) data;
-
-/** Generates the given main members documentation section.
-
-This is sent from @c generateObjectMembersSectionToData:() for each group of members that
-has at least one documented entry. This is where the following messages are sent to the
-subclass:
-- @c appendIndexGroupHeaderToData:type:()
-- @c appendIndexGroupItemToData:fromItem:index:type:()
-- @c appendIndexGroupFooterToData:type:()
-
-The @c type parameter can be one of the following:
-- @c kTKIndexGroupClasses: This group will append all classes.
-- @c kTKIndexGroupProtocols: This group will append all protocols.
-- @c kTKIndexGroupCategories: This group will append all categories.
-
-@param data The @c NSMutableData to append to.
-@param nodes The array of @c NSXMLElement instances representing individual members.
-@param type The type of the instances.
-@exception NSException Thrown if generation fails.
-@see generateObjectMembersSectionToData:
-*/
-- (void) generateObjectMemberSectionToData:(NSMutableData*) data
- fromNodes:(NSArray*) nodes
- type:(int) type;
-
-//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Index generation helpers
-//////////////////////////////////////////////////////////////////////////////////////////
-
-/** Generates the index groups documentation sections.
-
-This is sent from @c generateIndexGroupSectionsToData:(). It collects the group data
-and then sends @c generateIndexGroupSectionToData:fromNodes:type:() for each detected
-group.
-
-@param data The @c NSMutableData to append to.
-@exception NSException Thrown if generation fails.
-@see generateOutputForIndex
-@see generateIndexGroupSectionToData:fromNodes:type:
-*/
-- (void) generateIndexGroupSectionsToData:(NSMutableData*) data;
-
-/** Generates the given main members documentation section.
-
-This is sent from @c generateIndexGroupSectionsToData:() for each group that has at
-least one member. This is where the following messages are sent to the subclass:
-- @c appendIndexGroupHeaderToData:type:()
-- @c appendIndexGroupItemToData:fromItem:index:type:()
-- @c appendIndexGroupFooterToData:type:()
-
-The @c type parameter can be one of the following:
-- @c kTKObjectMemberTypeClass: The @c nodes describes class members.
-- @c kTKObjectMemberTypeInstance: The @c nodes describes instance members.
-- @c kTKObjectMemberTypeProperty: The @c nodes describes properties.
-
-@param data The @c NSMutableData to append to.
-@param nodes The array of @c NSXMLElement instances representing individual members.
-@param type The type of the instances.
-@exception NSException Thrown if generation fails.
-@see generateObjectMembersSectionToData:
-*/
-- (void) generateIndexGroupSectionToData:(NSMutableData*) data
- fromNodes:(NSArray*) nodes
- type:(int) type;
-
-//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Various helper methods
-//////////////////////////////////////////////////////////////////////////////////////////
-
-/** Converts all common placeholders in the given clean XML.
-
-The method eventually returns new @c NSXMLDocument instance which can be used for
-output generation.
-
-@param document The original clean XML.
-@return Returns new autoreleased @c NSXMLDocument with all common placeholders replaced.
-@exception NSException Thrown if convertion fails.
-*/
-- (NSXMLDocument*) convertPlaceholdersInMarkup:(NSXMLDocument*) document;
-
-@end
-
-//////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////////////
@implementation OutputGenerator
//////////////////////////////////////////////////////////////////////////////////////////
-/// @name Construction & destruction
+#pragma mark Initialization & disposal
//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
-- (id) init
+- (id) initWithDatabase:(NSMutableDictionary*) data
{
self = [super init];
- if (self != nil)
+ if (self)
{
cmd = [CommandLineParser sharedInstance];
+ manager = [NSFileManager defaultManager];
+ database = [data retain];
+ dependentGenerators = [[NSMutableArray alloc] init];
}
return self;
}
@@ -227,432 +32,139 @@ - (id) init
//----------------------------------------------------------------------------------------
- (void) dealloc
{
- self.projectName = nil;
- self.lastUpdated = nil;
cmd = nil;
+ manager = nil;
+ [database release], database = nil;
+ [dependentGenerators release], dependentGenerators = nil;
[super dealloc];
}
//////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Generation entry points
+#pragma mark Dependencies handling
//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
-- (void) generateOutputForObject:(NSDictionary*) data
+- (void) registerDependentGenerator:(id<OutputProcessing>) generator
{
- NSParameterAssert(data != nil);
-
- @try
- {
- // Assign the parameters and replace all placeholder templates.
- objectMarkup = [[self convertPlaceholdersInMarkup:[data objectForKey:kTKDataObjectMarkupKey]] retain];
- objectData = data;
-
- // Generate the data.
- logVerbose(@"- Generating output for object '%@'...", self.objectName);
- NSData* result = [self outputDataForObject];
-
- // Save the data.
- if (result && [result length] > 0)
- {
- NSString* relativePath = [objectData objectForKey:kTKDataObjectRelPathKey];
- NSString* filename = [cmd.outputCleanXHTMLPath stringByAppendingPathComponent:relativePath];
- NSString* extension = [self outputFilesExtension];
- filename = [filename stringByReplacingOccurrencesOfString:kTKPlaceholderExtension withString:extension];
-
- logDebug(@" - Saving object output to '%@'...", filename);
- if (![result writeToFile:filename atomically:NO])
- {
- NSString* message = [NSString stringWithFormat:@"Failed saving object output to '%@'!", filename];
- logError(@"Failed saving clean object output!");
- [Systemator throwExceptionWithName:kTKConverterException withDescription:message];
- }
- wasFileCreated = YES;
- }
-
- }
- @finally
- {
- [objectMarkup release];
- objectData = nil;
- }
+ NSParameterAssert(generator != nil);
+ [dependentGenerators addObject:generator];
}
-//----------------------------------------------------------------------------------------
-- (void) generateOutputForIndex:(NSDictionary*) data
-{
- NSParameterAssert(data != nil);
-
- @try
- {
- // Assign the parameters and replace all placeholder templates.
- indexMarkup = [[self convertPlaceholdersInMarkup:[data objectForKey:kTKDataMainIndexKey]] retain];
- indexData = data;
-
- // Generate the data.
- logVerbose(@"- Generating output for index...");
- NSData* result = [self outputDataForIndex];
-
- // Save the data.
- if (result && [result length] > 0)
- {
- NSString* filename = [cmd.outputCleanXHTMLPath stringByAppendingPathComponent:@"index"];
- filename = [filename stringByAppendingString:[self outputFilesExtension]];
-
- logDebug(@" - Saving index output to '%@'...", filename);
- if (![result writeToFile:filename atomically:NO])
- {
- NSString* message = [NSString stringWithFormat:@"Failed saving index output to '%@'!", filename];
- logError(@"Failed saving clean index output!");
- [Systemator throwExceptionWithName:kTKConverterException withDescription:message];
- }
- wasFileCreated = YES;
- }
- }
- @finally
- {
- [indexMarkup release];
- indexData = nil;
- }
-}
-
-//----------------------------------------------------------------------------------------
-- (void) generateOutputForHierarchy:(NSDictionary*) data
-{
- NSParameterAssert(data != nil);
-
- @try
- {
- // Assign the parameters and replace all placeholder templates.
- hierarchyMarkup = [[self convertPlaceholdersInMarkup:[data objectForKey:kTKDataMainHierarchyKey]] retain];
- hierarchyData = data;
-
- // Generate the data.
- logVerbose(@"- Generating output for hierarchy...");
- NSData* result = [self outputDataForHierarchy];
-
- // Save the data.
- if (result && [result length] > 0)
- {
- NSString* filename = [cmd.outputCleanXHTMLPath stringByAppendingPathComponent:@"hierarchy"];
- filename = [filename stringByAppendingString:[self outputFilesExtension]];
-
- logDebug(@" - Saving hierarchy output to '%@'...", filename);
- if (![result writeToFile:filename atomically:NO])
- {
- NSString* message = [NSString stringWithFormat:@"Failed saving hierarchy output to '%@'!", filename];
- logError(@"Failed saving clean hierarchy output!");
- [Systemator throwExceptionWithName:kTKConverterException withDescription:message];
- }
- wasFileCreated = YES;
- }
- }
- @finally
- {
- [hierarchyMarkup release];
- hierarchyData = nil;
- }
-}
-
-//----------------------------------------------------------------------------------------
-- (void) generationStarting
-{
- wasFileCreated = NO;
-}
-
-//----------------------------------------------------------------------------------------
-- (void) generationFinished
-{
-}
+//////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark Subclass handling
+//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
-- (NSString*) outputFilesExtension
+- (void) generateSpecificOutput
{
- [Systemator throwExceptionWithName:kTKConverterException
- withDescription:@"Output file extension is not provided!"];
- return nil;
}
//////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Objects output generation handling
+#pragma mark OutputProcessing protocol implementation
//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
-- (NSData*) outputDataForObject
+- (void) outputGenerationStarting
{
- NSMutableData* result = [NSMutableData data];
- [self appendObjectHeaderToData:result];
- [self generateObjectInfoSectionToData:result];
- [self generateObjectOverviewSectionToData:result];
- [self generateObjectTasksSectionToData:result];
- [self generateObjectMembersSectionToData:result];
- [self appendObjectFooterToData:result];
- return result;
}
//----------------------------------------------------------------------------------------
-- (void) generateObjectInfoSectionToData:(NSMutableData*) data
+- (void) outputGenerationFinished
{
- // Get all nodes that describe the object information.
- NSArray* baseNodes = [self.objectMarkup nodesForXPath:@"object/base" error:nil];
- NSArray* protocolNodes = [self.objectMarkup nodesForXPath:@"object/protocol" error:nil];
- NSArray* fileNodes = [self.objectMarkup nodesForXPath:@"object/file" error:nil];
-
- // If at least one is present, continue.
- if ([baseNodes count] > 0 || [protocolNodes count] > 0 || [fileNodes count] > 0)
- {
- int index = 0;
- [self appendObjectInfoHeaderToData:data];
- [self generateObjectInfoSectionToData:data fromNodes:baseNodes index:&index type:kTKObjectInfoItemInherits];
- [self generateObjectInfoSectionToData:data fromNodes:protocolNodes index:&index type:kTKObjectInfoItemConforms];
- [self generateObjectInfoSectionToData:data fromNodes:fileNodes index:&index type:kTKObjectInfoItemDeclared];
- [self appendObjectInfoFooterToData:data];
- }
}
//----------------------------------------------------------------------------------------
-- (void) generateObjectInfoSectionToData:(NSMutableData*) data
- fromNodes:(NSArray*) items
- index:(int*) index
- type:(int) type;
-{
- if ([items count] > 0)
- {
- [self appendObjectInfoItemToData:data fromItems:items index:*index type:type];
- (*index)++;
- }
-}
-
-//----------------------------------------------------------------------------------------
-- (void) generateObjectOverviewSectionToData:(NSMutableData*) data
-{
- // Append the object overview if the object is documented. Note that we only take
- // the first description node if there are more (shouldn't happen, but just in case).
- NSArray* overviewNodes = [self.objectMarkup nodesForXPath:@"object/description" error:nil];
- if ([overviewNodes count] > 0)
- {
- NSXMLElement* overviewNode = [overviewNodes objectAtIndex:0];
- [self appendObjectOverviewToData:data fromItem:overviewNode];
- }
-}
-
-//----------------------------------------------------------------------------------------
-- (void) generateObjectTasksSectionToData:(NSMutableData*) data
+- (void) generateOutput
{
- // Appends the tasks with short method descriptions if at least one section is
- // found with at least one member. Note that the sections are only handled if there's
- // at least one member, otherwise these messages are not sent, even if (empty)
- // sections are encountered.
- NSArray* sectionNodes = [self.objectMarkup nodesForXPath:@"object/sections/section" error:nil];
- if ([sectionNodes count] > 0)
+ if (self.isOutputGenerationEnabled)
{
- BOOL sectionsHandled = NO;
- for (int i = 0; i < [sectionNodes count]; i++)
+ // Create required output directories.
+ [self createOutputDirectories];
+
+ // Generate the output for this class.
+ [self outputGenerationStarting];
+ [self generateSpecificOutput];
+ [self outputGenerationFinished];
+
+ // Process all dependent generators. Note that this recursively generates the
+ // output for all nested dependencies as well. Note that we only need to send
+ // generateOutput message, it will take care of creating directories and the rest.
+ BOOL outputWasGenerated = NO;
+ for (id<OutputProcessing> dependentGenerator in dependentGenerators)
{
- NSXMLElement* sectionNode = [sectionNodes objectAtIndex:i];
- NSArray* memberNodes = [sectionNode nodesForXPath:@"member" error:nil];
- if ([memberNodes count] > 0)
+ if (dependentGenerator.isOutputGenerationEnabled)
{
- // Append the sections header if not yet.
- if (!sectionsHandled)
- {
- [self appendObjectTasksHeaderToData:data];
- sectionsHandled = YES;
- }
-
- // Append section header.
- [self appendObjectTaskHeaderToData:data fromItem:sectionNode index:i];
-
- // Process all section members.
- for (int n = 0; n < [memberNodes count]; n++)
- {
- NSXMLElement* memberNode = [memberNodes objectAtIndex:n];
- [self appendObjectTaskMemberToData:data fromItem:memberNode index:n];
- }
-
- // Append section footer.
- [self appendObjectTaskFooterToData:data fromItem:sectionNode index:i];
+ [dependentGenerator generateOutput];
+ outputWasGenerated = YES;
}
}
- // Append sections footer.
- if (sectionsHandled) [self appendObjectTasksFooterToData:data];
+ // If temporary files should be removed after creating and at least one dependent
+ // generator output was created, we can remove our files.
+ if (cmd.cleanTempFilesAfterBuild && outputWasGenerated)
+ {
+ [self removeOutputDirectories];
+ }
}
}
//----------------------------------------------------------------------------------------
-- (void) generateObjectMembersSectionToData:(NSMutableData*) data
+- (BOOL) isOutputGenerationEnabled
{
- // Get the lists of all member nodes for each member type.
- NSArray* classMethodNodes = [self.objectMarkup
- nodesForXPath:@"object/sections/section/member[@kind='class-method']"
- error:nil];
- NSArray* instanceMethodNodes = [self.objectMarkup
- nodesForXPath:@"object/sections/section/member[@kind='instance-method']"
- error:nil];
- NSArray* propertyNodes = [self.objectMarkup
- nodesForXPath:@"object/sections/section/member[@kind='property']"
- error:nil];
+ // By default we always return yes, so concrete subclasses which should always be
+ // enabled don't have to handle this. However subclasses which can optionally be
+ // disabled, should override and return proper value.
+ return YES;
+}
- // Append the main members documentation descriptions if at least one member group
- // is found with at least one documented member.
- if ([classMethodNodes count] > 0 ||
- [instanceMethodNodes count] > 0 ||
- [propertyNodes count] > 0)
- {
- // Ask the subclass to append members documentation header.
- [self appendObjectMembersHeaderToData:data];
-
- // Process all lists.
- [self generateObjectMemberSectionToData:data fromNodes:classMethodNodes type:kTKObjectMemberTypeClass];
- [self generateObjectMemberSectionToData:data fromNodes:instanceMethodNodes type:kTKObjectMemberTypeInstance];
- [self generateObjectMemberSectionToData:data fromNodes:propertyNodes type:kTKObjectMemberTypeProperty];
-
- // Ask the subclass to append members documentation footer.
- [self appendObjectMembersFooterToData:data];
- }
+//----------------------------------------------------------------------------------------
+- (void) createOutputDirectories
+{
}
//----------------------------------------------------------------------------------------
-- (void) generateObjectMemberSectionToData:(NSMutableData*) data
- fromNodes:(NSArray*) nodes
- type:(int) type
+- (void) removeOutputDirectories
{
- if ([nodes count] > 0)
- {
- // Ask the subclass to append members group header.
- [self appendObjectMemberGroupHeaderToData:data type:type];
-
- // Ask the subclass to document all members of this group.
- for (int i = 0; i < [nodes count]; i++)
- {
- NSXMLElement* node = [nodes objectAtIndex:i];
- [self appendObjectMemberToData:data fromItem:node index:i];
- }
-
- // Ask the subclass to append members group footer.
- [self appendObjectMemberGroupFooterToData:data type:type];
- }
}
//////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Index output generation handling
+#pragma mark OutputInfoProvider protocol implementation
//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
-- (NSData*) outputDataForIndex
+- (NSString*) outputObjectFilenameForObject:(NSDictionary*) objectData
{
- NSMutableData* result = [NSMutableData data];
- [self appendIndexHeaderToData:result];
- [self generateIndexGroupSectionsToData:result];
- [self appendIndexFooterToData:result];
- return result;
+ NSString* path = [objectData objectForKey:kTKDataObjectRelPathKey];
+ return [self pathByReplacingTemplatePlaceholdersInPath:path];
}
//----------------------------------------------------------------------------------------
-- (void) generateIndexGroupSectionsToData:(NSMutableData*) data
+- (NSString*) outputIndexFilename
{
- NSArray* classNodes = [self.indexMarkup nodesForXPath:@"project/object[@kind='class']" error:nil];
- NSArray* categoryNodes = [self.indexMarkup nodesForXPath:@"project/object[@kind='category']" error:nil];
- NSArray* protocolNodes = [self.indexMarkup nodesForXPath:@"project/object[@kind='protocol']" error:nil];
-
- [self generateIndexGroupSectionToData:data
- fromNodes:classNodes
- type:kTKIndexGroupClasses];
- [self generateIndexGroupSectionToData:data
- fromNodes:protocolNodes
- type:kTKIndexGroupProtocols];
- [self generateIndexGroupSectionToData:data
- fromNodes:categoryNodes
- type:kTKIndexGroupCategories];
+ return [NSString stringWithFormat:@"index%@", [self outputFilesExtension]];
}
//----------------------------------------------------------------------------------------
-- (void) generateIndexGroupSectionToData:(NSMutableData*) data
- fromNodes:(NSArray*) nodes
- type:(int) type
+- (NSString*) outputHierarchyFilename
{
- if ([nodes count] > 0)
- {
- [self appendIndexGroupHeaderToData:data type:type];
- for (int i = 0; i < [nodes count]; i++)
- {
- NSXMLElement* node = [nodes objectAtIndex:i];
- [self appendIndexGroupItemToData:data
- fromItem:node
- index:i
- type:type];
- }
- [self appendIndexGroupFooterToData:data type:type];
- }
+ return [NSString stringWithFormat:@"hierarchy%@", [self outputFilesExtension]];
}
-//////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Hierarchy output generation handling
-//////////////////////////////////////////////////////////////////////////////////////////
-
//----------------------------------------------------------------------------------------
-- (NSData*) outputDataForHierarchy
+- (NSString*) outputFilesExtension
{
- // Note that we could use the hierarchies data directly instead of relying on the
- // generated XML and it would probably be more optimized too. However using XML
- // ensures consistent parsing code with the rest of the generation methods and
- // perhaps even more important - it uses the same data that external utilities
- // might use if they are only interested in generating the XML from appledoc.
- NSMutableData* result = [NSMutableData data];
- NSArray* rootNodes = [self.hierarchyMarkup nodesForXPath:@"project/object" error:nil];
- if ([rootNodes count] > 0)
- {
- [self appendHierarchyHeaderToData:result];
- [self appendHierarchyGroupHeaderToData:result];
- for (int i = 0; i < [rootNodes count]; i++)
- {
- NSXMLElement* rootNode = [rootNodes objectAtIndex:i];
- [self appendHierarchyGroupItemToData:result
- fromItem:rootNode
- index:i];
- }
- [self appendHierarchyGroupFooterToData:result];
- [self appendHierarchyFooterToData:result];
- }
-
- return result;
+ return @"";
}
//////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Common helper methods
+#pragma mark Helper methods
//////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------
-- (NSXMLDocument*) convertPlaceholdersInMarkup:(NSXMLDocument*) document
+- (NSString*) pathByReplacingTemplatePlaceholdersInPath:(NSString*) path
{
- // The handling is simple, but resource intensive - convert the XML to string,
- // replace all placeholder occurences and re-create the new document from the
- // resulting string.
- NSString* string = [document XMLString];
- string = [self convertPathByReplacingPlaceholders:string];
-
- // Create the new XMl document.
- NSError* error = nil;
- NSXMLDocument* result = [[[NSXMLDocument alloc] initWithXMLString:string
- options:0
- error:&error] autorelease];
- if (error)
- {
- logError(@"Converting placeholders XML failed!");
- [Systemator throwExceptionWithName:kTKConverterException basedOnError:error];
- }
-
- // Return the new document.
- return result;
+ return [path stringByReplacingOccurrencesOfString:kTKPlaceholderExtension
+ withString:[self outputFilesExtension]];
}
-//////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Properties
-//////////////////////////////////////////////////////////////////////////////////////////
-
-@synthesize projectName;
-@synthesize lastUpdated;
-@synthesize wasFileCreated;
-
@end
View
68 OutputInfoProvider.h
@@ -0,0 +1,68 @@
+//
+// OutputInfoProvider.h
+// appledoc
+//
+// Created by Tomaz Kragelj on 12.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+/** The @c OutputInfoProvider protocol defines methods that objects which need to
+provide information about their output must implement.
+
+The main argument for this interface is to decouple concrete @c OutputGenerator classes
+from their dependent output generators. For example documentation set generator needs to
+know the names and extensions used by the XHTML output generator. However to allow
+arbitrary HTML output generator to be used with documentation set, the documentation set
+output generator needs any object that conforms to @c OutputInfoProvider so that it
+can get all required information it needs.
+*/
+@protocol OutputInfoProvider
+
+//////////////////////////////////////////////////////////////////////////////////////////
+/// @name Output information providing
+//////////////////////////////////////////////////////////////////////////////////////////
+
+/** Returns the given object file name.
+
+@param objectData The @c NSDictionary from main database representing the object data.
+@return Returns the given object file name, including relative path from the base
+ directory and extension.
+@see outputIndexFilename
+@see outputHierarchyFilename
+@see outputFilesExtension
+*/
+- (NSString*) outputObjectFilenameForObject:(NSDictionary*) objectData;
+
+/** Returns the index file name.
+
+@return Returns the index file name, including relative path from the base directory and
+ extension.
+@see outputObjectFilenameForObject:
+@see outputHierarchyFilename
+@see outputFilesExtension
+*/
+- (NSString*) outputIndexFilename;
+
+/** Returns the hierarchy file name.
+
+@return Returns the hierarchy file name, including relative path from the base directory
+ and extension.
+@see outputObjectFilenameForObject:
+@see outputIndexFilename
+@see outputFilesExtension
+*/
+- (NSString*) outputHierarchyFilename;
+
+/** Returns the output files extension.
+
+@see outputObjectFilenameForObject:
+@see outputIndexFilename
+@see outputHierarchyFilename
+*/
+- (NSString*) outputFilesExtension;
+
+@end
View
46 OutputProcessing.h
@@ -0,0 +1,46 @@
+//
+// OutputProcessing.h
+// appledoc
+//
+// Created by Tomaz Kragelj on 12.6.09.
+// Copyright (C) 2009, Tomaz Kragelj. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+/** The @c OutputProcessing protocol defines methods that an output processing or
+generating class must implement.
+
+The methods consist of two groups. The main group is associated with the actual output
+generation, while the helper group with additional tasks such as creating and removing
+directories.
+*/
+@protocol OutputProcessing
+
+//////////////////////////////////////////////////////////////////////////////////////////
+/// @name Output generation entry points
+//////////////////////////////////////////////////////////////////////////////////////////
+
+/** Notifies output generator to start processing the data and generate output.
+
+This message is sent only to conformers which return @c YES from
+@c isOutputGenerationEnabled(). The conformers which receive the message should process
+it without having to check again. It is the responsibility of the clients to ensure that
+this message is sent only if output generation is enabled.
+
+@exception NSException Thrown if output generation fails.
+@see isOutputGenerationEnabled
+*/
+- (void) generateOutput;
+
+/** Determines whether the specific output handled by conformer should be generated or not.
+
+This answers the question "did user select the given output generation or not?".
+
+@see generateOutput
+*/
+@property(readonly) BOOL isOutputGenerationEnabled;
+
+@end
View
67 Systemator.h
@@ -16,6 +16,10 @@ Note that this class only contains class methods, so no instance is needed.
*/
@interface Systemator : NSObject
+//////////////////////////////////////////////////////////////////////////////////////////
+/// @name Tasks and processes handling
+//////////////////////////////////////////////////////////////////////////////////////////
+
/** Runs the given task.
This is a helper method which facilitates running external commands. It creates a task,
@@ -43,6 +47,54 @@ temporary file removed. This command allows the clients to properly handle shell
*/
+ (void) runShellTaskWithCommand:(NSString*) command;
+//////////////////////////////////////////////////////////////////////////////////////////
+/// @name XML helpers
+//////////////////////////////////////////////////////////////////////////////////////////
+
+/** Applies the XSLT from the given file to the document and returns the resulting object.
+
+This will first load the XSLT from the given file and will apply it to the document. It
+will return the transformed object which is either an @c NSXMLDocument if transformation
+created an XML or @c NSData otherwise. If transformation failed, @c nil is returned and
+error description is passed over the @c error parameter.
+
+This message internally sends @c applyXSLTFromFile:toDocument:arguments:error:() with
+arguments set to @c nil.
+
+@param filename The name of the XSLT file including full path.
+@param document The @c NSXMLDocument to transform.
+@param error If transformation failed, error is reported here.
+@return Returns transformed object or @c nil if transformation failed.
+@see applyXSLTFromFile:toDocument:arguments:error:
+*/
++ (id) applyXSLTFromFile:(NSString*) filename
+ toDocument:(NSXMLDocument*) document
+ error:(NSError**) error;
+
+/** Applies the XSLT from the given file to the document and returns the resulting object.
+
+This will first load the XSLT from the given file and will apply it to the document. It
+will return the transformed object which is either an @c NSXMLDocument if transformation
+created an XML or @c NSData otherwise. If transformation failed, @c nil is returned and
+error description is passed over the @c error parameter.
+
+