mirror of
https://github.com/gnustep/libs-gsweb.git
synced 2025-02-22 19:21:23 +00:00
* GSWeb.framework/GSWWOCompatibility.h/.m: added * GSWeb.framework/GNUmakefile: added GSWWOCompatibility.h/.m * GSWeb.framework/GSWApplication.h/m: added WOApplicationMain, handle WO/GSWeb names * GSWeb.framework/GSWContext.m: handle WO/GSWeb names, added traces * GSWeb.framework/GSWConstants.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWDynamicURLString.m: handle WO/GSWeb names * GSWeb.framework/GSWProjectBundle.m/.h: handle WO/GSWeb names, suppress warnings * GSWeb.framework/GSWSession.m: handle WO/GSWeb names * GSWeb.framework/GSWRequest.m: handle WO/GSWeb names * GSWeb.framework/GSWTemplateParser.m: handle WO/GSWeb names, added tag counts to help errors hunt * GSWeb.framework/GSWBundle.m: handle WO/GSWeb names, added traces * GSWeb.framework/GSWResourceManager.m: handle WO/GSWeb names * GSWeb.framework/GSWURLValuedElementData.m: handle WO/GSWeb names * GSWeb.framework/GSWComponentRequestHandler.m: handle WO/GSWeb names * GSWeb.framework/GSWDirectAction.m: handle WO/GSWeb names * GSWeb.framework/GSWForm.m/.h: handle WO/GSWeb names * GSWeb.framework/GSWHyperlink.m/.h: handle WO/GSWeb names * GSWeb.framework/GSWResourceRequestHandler.m: handle WO/GSWeb names * GSWeb.framework/GSWDirectActionRequestHandler.m: handle WO/GSWeb names * GSWeb.framework/GSWActiveImage.m/.h: handle WO/GSWeb names * GSWeb.framework/GSWBindingNameAssociation.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWBrowser.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWComponent.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWHTMLURLValuedElement.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWImageButton.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWInput.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWPopUpButton.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWString.h/.m: handle WO/GSWeb names * GSWeb.framework/GSWAssociation.m: handle WO/GSWeb names * GSWeb.framework/GSWCheckBox.m: handle WO/GSWeb names * GSWeb.framework/GSWCheckBoxList.m: handle WO/GSWeb names * GSWeb.framework/GSWComponentDefinition.m: handle WO/GSWeb names * GSWeb.framework/GSWRadioButton.m: handle WO/GSWeb names * GSWeb.framework/GSWRadioButtonList.m: handle WO/GSWeb names * GSWeb.framework/GSWText.m: handle WO/GSWeb names * GSWeb.framework/GSWTextField.m: handle WO/GSWeb names * GSWeb.framework/GSWDeployedBundle.m: warnings * GSWeb.framework/GSWeb.h: added include GSWeb/GSWSessionTimeOut.h, GSWWOCompatibility.h * GSWeb.framework/GSWAdaptor.m: traces * GSWeb.framework/GSWDefaultAdaptor.m: handle WO/GSWeb names, added traces * GSWeb.framework/GSWDefaultAdaptorThread.m/.h: handle WO/GSWeb names * GSWeb.framework/NSNonBlockingFileHandle.m: added traces * GSWeb.framework/GSWTemplateParserANTLR.m: handle WO/GSWeb names * GSWeb.framework/GSWTemplateParserXML.m: handle WO/GSWeb names added tag count to help errors hunt remove "Tag gsweb invalid" message handle unicode strings in node content traces remove html and body tags if they are not present in the template * GSWeb.framework/GSWTemplateParseXML.h: added ivar _isHTMLTag, _isBodyTag * GSWeb.framework/GSWSessionTimeOutManager.m: dealloc sessionOrderedTimeOuts instead of deallocating 2 times sessionTimeOuts * GSWExtensions.framework/French.lproj/GSWSessionRestorationErrorPage.gswc/GSWSessionRestorationErrorPage.html: tag mismatch, Encode french characters * GSWExtensions.framework/GSWSessionRestorationErrorPage.gswc/GSWSessionRestorationErrorPage.html: tag mismatch * GSWHTMLBareString.m: handle unicode strings in description * GSWExtensions.framework/French.lproj/GSWExceptionPage.gswc/GSWExceptionPage.html: Encode french characters, Tag Mismatch * GSWExtensions.framework/French.lproj/GSWPageRestorationErrorPage.gswc/GSWPageRestorationErrorPage.html: Encode french characters * GSWExtensions.framework/French.lproj/GSWSessionCreationErrorPage.gswc/GSWSessionCreationErrorPage.html: Encode french characters * GSWExtensions.framework/GSWExceptionPage.gswc/GSWExceptionPage.html: Tag Mismatch * GSWExtensions.framework/GSWExceptionPage.gswc/GSWExceptionPage.gswd: added convertHTMLEntities for strings * GSWeb.framework/GSWRepetition.m: added traces, fix "count" property bug, standardize ivars * GSWeb.framework/NSObject+IVarAccess+PerformSel.m: added traces, handle underscored ivars search git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@9332 72102866-910b-0410-8b05-ffd578937521
890 lines
37 KiB
Objective-C
890 lines
37 KiB
Objective-C
/* GSWTemplateParserXML.m - GSWeb: Class GSWTemplateParserXML
|
|
Copyright (C) 1999 Free Software Foundation, Inc.
|
|
|
|
Written by: Manuel Guesdon <mguesdon@sbuilders.com>
|
|
Date: Mar 1999
|
|
|
|
This file is part of the GNUstep Web Library.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
static char rcsId[] = "$Id$";
|
|
|
|
#include <GSWeb/GSWeb.h>
|
|
#include <SAX.h>
|
|
|
|
extern xmlParserInputPtr xmlNewStringInputStream(xmlParserCtxtPtr ctxt,
|
|
const xmlChar *buffer);
|
|
|
|
static NSLock* GSXMLParserLock=nil;
|
|
static NSMutableDictionary* DTDCache=nil;
|
|
|
|
//====================================================================
|
|
@implementation GSWTemplateParserSAXHandler
|
|
|
|
//--------------------------------------------------------------------
|
|
+ (void) initialize
|
|
{
|
|
// Initialize DTD Cache, and Lock
|
|
if (self==[GSWTemplateParserSAXHandler class])
|
|
{
|
|
if (!DTDCache)
|
|
DTDCache=[NSMutableDictionary new];
|
|
if (!GSXMLParserLock)
|
|
GSXMLParserLock=[NSRecursiveLock new];
|
|
};
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
+(void)dealloc
|
|
{
|
|
// Dealloc DTD Cache and Lock
|
|
if (self==[GSWTemplateParserSAXHandler class])
|
|
{
|
|
DESTROY(DTDCache);
|
|
DESTROY(GSXMLParserLock);
|
|
};
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
/*"Lock"*/
|
|
+(void)lock
|
|
{
|
|
NS_DURING
|
|
{
|
|
[GSXMLParserLock lock];
|
|
}
|
|
NS_HANDLER
|
|
{
|
|
NSLog(@"EXCEPTION:(GSXMLParserLock lock) %@ (%@) [%s %d]",localException,[localException reason],__FILE__,__LINE__);
|
|
[localException raise];
|
|
};
|
|
NS_ENDHANDLER;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
/*"Unlock"*/
|
|
+(void)unlock
|
|
{
|
|
NS_DURING
|
|
{
|
|
[GSXMLParserLock unlock];
|
|
}
|
|
NS_HANDLER
|
|
{
|
|
NSLog(@"EXCEPTION:(GSXMLParserLock unlock) %@ (%@) [%s %d]",localException,[localException reason],__FILE__,__LINE__);
|
|
[localException raise];
|
|
};
|
|
NS_ENDHANDLER;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
/*"Find cached DTD Content for Key url"*/
|
|
+(NSString*)cachedDTDContentForKey:(NSString*)url
|
|
{
|
|
NSString* content=nil;
|
|
[self lock];
|
|
content=[DTDCache objectForKey:url];
|
|
[self unlock];
|
|
return content;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
/*"Cache DTD Content externalContent for Key url"*/
|
|
+(void)setCachedDTDContent:(NSString*)externalContent
|
|
forKey:(NSString*)url
|
|
{
|
|
[self lock];
|
|
[DTDCache setObject:externalContent
|
|
forKey:url];
|
|
[self unlock];
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
+(id)handlerWithTemplateParser:(GSWTemplateParser*)templateParser_
|
|
{
|
|
return AUTORELEASE([[self alloc] initWithTemplateParser:templateParser_]);
|
|
};
|
|
|
|
extern void externalSubset (void *ctx,
|
|
const xmlChar *name,
|
|
const xmlChar *ExternalID,
|
|
const xmlChar *SystemID);
|
|
|
|
//--------------------------------------------------------------------
|
|
-(id)initWithTemplateParser:(GSWTemplateParser*)templateParser_
|
|
{
|
|
if ((self=[self init]))
|
|
{
|
|
_templateParser=templateParser_;
|
|
NSLog(@"my sax lib=%p",lib);
|
|
if (lib)
|
|
{
|
|
xmlSAXHandlerPtr def=NULL;
|
|
if ([_templateParser isKindOfClass:[GSWTemplateParserXMLHTML class]])
|
|
def=&htmlDefaultSAXHandler;
|
|
else
|
|
def=&xmlDefaultSAXHandler;
|
|
((xmlSAXHandlerPtr)lib)->internalSubset = def->internalSubset;
|
|
((xmlSAXHandlerPtr)lib)->isStandalone = def->isStandalone;
|
|
((xmlSAXHandlerPtr)lib)->hasInternalSubset = def->hasInternalSubset;
|
|
((xmlSAXHandlerPtr)lib)->hasExternalSubset = def->hasExternalSubset;
|
|
((xmlSAXHandlerPtr)lib)->resolveEntity = def->resolveEntity;
|
|
((xmlSAXHandlerPtr)lib)->getEntity = def->getEntity;
|
|
((xmlSAXHandlerPtr)lib)->entityDecl = def->entityDecl;
|
|
((xmlSAXHandlerPtr)lib)->notationDecl = def->notationDecl;
|
|
((xmlSAXHandlerPtr)lib)->attributeDecl = def->attributeDecl;
|
|
((xmlSAXHandlerPtr)lib)->elementDecl = def->elementDecl;
|
|
((xmlSAXHandlerPtr)lib)->unparsedEntityDecl = def->unparsedEntityDecl;
|
|
((xmlSAXHandlerPtr)lib)->startDocument = def->startDocument;
|
|
((xmlSAXHandlerPtr)lib)->endDocument = def->endDocument;
|
|
((xmlSAXHandlerPtr)lib)->startElement = def->startElement;
|
|
((xmlSAXHandlerPtr)lib)->endElement = def->endElement;
|
|
((xmlSAXHandlerPtr)lib)->reference = def->reference;
|
|
((xmlSAXHandlerPtr)lib)->characters = def->characters;
|
|
((xmlSAXHandlerPtr)lib)->ignorableWhitespace = def->ignorableWhitespace;
|
|
((xmlSAXHandlerPtr)lib)->processingInstruction = def->processingInstruction;
|
|
((xmlSAXHandlerPtr)lib)->comment = def->comment;
|
|
// ((xmlSAXHandlerPtr)lib)->warning = xmlParserWarning;
|
|
// ((xmlSAXHandlerPtr)lib)->error = xmlParserError;
|
|
// ((xmlSAXHandlerPtr)lib)->fatalError = xmlParserError;
|
|
((xmlSAXHandlerPtr)lib)->getParameterEntity = def->getParameterEntity;
|
|
((xmlSAXHandlerPtr)lib)->cdataBlock = def->cdataBlock;
|
|
((xmlSAXHandlerPtr)lib)->externalSubset = def->externalSubset;
|
|
};
|
|
};
|
|
return self;
|
|
};
|
|
|
|
-(id)init
|
|
{
|
|
if ((self=[super init]))
|
|
{
|
|
};
|
|
return self;
|
|
};
|
|
|
|
/*
|
|
xmlParserInputPtr GSWTemplateParserSAXHandler_ExternalLoader(const char *systemId,
|
|
const char *publicId,
|
|
xmlParserCtxtPtr context)
|
|
{
|
|
// NSCAssert(context,@"No Parser Context");
|
|
// NSCAssert(context->_private,@"No GSSAXHandler reference in Parser Context");
|
|
// return [(GSSAXHandler*)(context->_private)resolveEntity:[NSString stringWithCString:publicId]
|
|
// systemID:[NSString stringWithCString:systemId]];
|
|
return NULL;
|
|
}
|
|
*/
|
|
|
|
//--------------------------------------------------------------------
|
|
//exemple:
|
|
// publicIdEntity
|
|
// -//IETF//DTD HTML//EN
|
|
// -//W3C//ENTITIES Special for XHTML//EN
|
|
// -//W3C//ENTITIES Symbols for XHTML//EN
|
|
// -//W3C//ENTITIES Latin 1 for XHTML//EN
|
|
// -//W3C//DTD XHTML 1.0 Transitional//EN
|
|
// -//W3C//DTD XHTML 1.0 Strict//EN
|
|
// -//W3C//DTD XHTML 1.0 Frameset//EN
|
|
// -//W3C//DTD HTML 4.01//EN
|
|
// -//W3C//DTD HTML 4.01 Transitional//EN
|
|
// -//W3C//DTD HTML 4.01 Frameset//EN
|
|
// -//IETF//DTD HTML//EN
|
|
// -//W3C//DTD HTML 3.2//EN
|
|
// systemIdEntity
|
|
// http://www.w3c.org/html.dtd
|
|
// html.dtd
|
|
|
|
-(xmlParserInputPtr)resolveEntity:(NSString*)publicIdEntity
|
|
systemID:(NSString*)systemIdEntity
|
|
{
|
|
NSString* externalContent=nil;
|
|
xmlParserInputPtr result = 0;
|
|
LOGObjectFnStart();
|
|
NSLog(@"resolveEntity:%@ systemID:%@ inParserContext:%p\n",
|
|
publicIdEntity,
|
|
systemIdEntity,
|
|
lib);
|
|
NSAssert(publicIdEntity || systemIdEntity,
|
|
@"resolveEntity:systemIdEntity: publicIdEntity and systemIdEntity are both nil");
|
|
if (systemIdEntity)
|
|
{
|
|
externalContent=[[self class] cachedDTDContentForKey:systemIdEntity];
|
|
if (!externalContent)
|
|
{
|
|
NSString* fileName=nil;
|
|
NSString* resourceName=systemIdEntity;
|
|
if ([[resourceName pathExtension] isEqual:@"dtd"])
|
|
resourceName=[resourceName stringByDeletingPathExtension];
|
|
fileName = [[NSBundle bundleForClass: [self class]]
|
|
pathForResource:resourceName
|
|
ofType:@"dtd"
|
|
inDirectory:@"DTDs"];
|
|
NSLog(@"systemIdEntity: fileName=%@ for Resource:%@",fileName,resourceName);
|
|
if (fileName)
|
|
{
|
|
externalContent=[NSString stringWithContentsOfFile:fileName];
|
|
};
|
|
externalContent=[NSString stringWithContentsOfFile:fileName];
|
|
if (externalContent)
|
|
{
|
|
NSString* gswebTag=@"\n<!ELEMENT gsweb %Flow;>
|
|
<!ATTLIST gsweb
|
|
%attrs;
|
|
>\n";
|
|
// name NMTOKEN; #IMPLIED
|
|
NSLog(@"gswebTag=\n%@",gswebTag);
|
|
externalContent=[externalContent stringByAppendingString:gswebTag];
|
|
|
|
[[self class] setCachedDTDContent:externalContent
|
|
forKey:systemIdEntity];
|
|
};
|
|
};
|
|
};
|
|
if (!externalContent && publicIdEntity)
|
|
{
|
|
externalContent=[[self class] cachedDTDContentForKey:publicIdEntity];
|
|
if (!externalContent)
|
|
{
|
|
//Well Known DTDs / Entities
|
|
if ([publicIdEntity hasPrefix:@"-//"])
|
|
{
|
|
// 0: -
|
|
// 1: W3C or IETF
|
|
// 2: DTD ... or ENTITIES ...
|
|
// 3: EN or ... (language)
|
|
NSArray* parts=[publicIdEntity componentsSeparatedByString:@"//"];
|
|
if ([parts count]>=2)
|
|
{
|
|
NSString* whatPart=[parts objectAtIndex:2];
|
|
if ([whatPart hasPrefix:@"DTD"])
|
|
{
|
|
NSString* resourceName=nil;
|
|
NSString* fileName=nil;
|
|
if ([whatPart rangeOfString:@"Transitional"].length>0)
|
|
resourceName=@"xhtml1-transitional.dtd";
|
|
else if ([whatPart rangeOfString:@"Strict"].length>0)
|
|
resourceName=@"xhtml1-strict.dtd";
|
|
else if ([whatPart rangeOfString:@"Frameset"].length>0)
|
|
resourceName=@"xhtml1-frameset.dtd";
|
|
else
|
|
{
|
|
NSLog(@"Unknown DTD: %@. Choose default: xhtml1-transitional.dtd",publicIdEntity);
|
|
resourceName=@"xhtml1-transitional.dtd"; // guess
|
|
};
|
|
if (resourceName)
|
|
{
|
|
if ([[resourceName pathExtension] isEqual:@"dtd"])
|
|
resourceName=[resourceName stringByDeletingPathExtension];
|
|
fileName = [[NSBundle bundleForClass: [self class]]
|
|
pathForResource:resourceName
|
|
ofType:@"dtd"
|
|
inDirectory:@"DTDs"];
|
|
NSLog(@"systemIdEntity: fileName=%@ for Resource:%@",fileName,publicIdEntity);
|
|
if (fileName)
|
|
{
|
|
externalContent=[NSString stringWithContentsOfFile:fileName];
|
|
};
|
|
};
|
|
}
|
|
else if ([whatPart hasPrefix:@"ENTITIES"])
|
|
{
|
|
NSString* resourceName=nil;
|
|
NSString* fileName=nil;
|
|
if ([whatPart rangeOfString:@"Symbols"].length>0)
|
|
resourceName=@"xhtml-symbol.ent";
|
|
else if ([whatPart rangeOfString:@"Special"].length>0)
|
|
resourceName=@"xhtml-special.ent";
|
|
else if ([whatPart rangeOfString:@"Latin 1"].length>0)
|
|
resourceName=@"xhtml-lat1.ent";
|
|
else
|
|
{
|
|
NSLog(@"Unknown ENTITIES: %@",publicIdEntity);
|
|
};
|
|
if (resourceName)
|
|
{
|
|
if ([[resourceName pathExtension] isEqual:@"ent"])
|
|
resourceName=[resourceName stringByDeletingPathExtension];
|
|
fileName = [[NSBundle bundleForClass: [self class]]
|
|
pathForResource:resourceName
|
|
ofType:@"ent"
|
|
inDirectory:@"DTDs"];
|
|
NSLog(@"systemIdEntity: fileName=%@ for Resource:%@",fileName,publicIdEntity);
|
|
if (fileName)
|
|
{
|
|
externalContent=[NSString stringWithContentsOfFile:fileName];
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{
|
|
NSLog(@"Unknown publicIdEntity %@",publicIdEntity);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
NSLog(@"Don't know how to parse publicIdEntity %@",publicIdEntity);
|
|
};
|
|
}
|
|
else
|
|
{
|
|
NSLog(@"Don't know what to do with publicIdEntity %@",publicIdEntity);
|
|
};
|
|
if (externalContent)
|
|
[[self class] setCachedDTDContent:externalContent
|
|
forKey:publicIdEntity];
|
|
};
|
|
};
|
|
if (externalContent)
|
|
{
|
|
result=xmlNewStringInputStream(lib,[externalContent cString]);
|
|
};
|
|
NSAssert2(result,@"Can't load external (publicIdEntity:%@ systemIdEntity:%@)",publicIdEntity,systemIdEntity);
|
|
NSLog(@"LOADED: resolveEntity:%@ systemID:%@ inParserContext:%p\n",
|
|
publicIdEntity,
|
|
systemIdEntity,
|
|
lib);
|
|
LOGObjectFnStop();
|
|
return result;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
-(void)warning:(NSString*)message
|
|
colNumber:(int)colNumber
|
|
lineNumber:(int)lineNumber
|
|
{
|
|
[[GSWApplication application] logWithFormat:@"%@ Warning (col %d,line %d): %@",
|
|
[_templateParser logPrefix],
|
|
colNumber,
|
|
lineNumber,
|
|
message];
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
-(void)error: (NSString*)message
|
|
colNumber:(int)colNumber
|
|
lineNumber:(int)lineNumber
|
|
{
|
|
NSString* testMessage=[[message lowercaseString] stringByTrimmingSpaces];
|
|
if (![testMessage isEqualToString:@"tag webobject invalid"]
|
|
&& ![testMessage isEqualToString:@"tag gsweb invalid"])
|
|
{
|
|
[[GSWApplication application] logErrorWithFormat:@"%@ Error (col %d,line %d): %@",
|
|
[_templateParser logPrefix],
|
|
colNumber,
|
|
lineNumber,
|
|
message];
|
|
};
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
-(void)fatalError: (NSString*)message
|
|
colNumber:(int)colNumber
|
|
lineNumber:(int)lineNumber
|
|
{
|
|
[[GSWApplication application] logErrorWithFormat:@"%@ Fatal Error (col %d,line %d): %@",
|
|
[_templateParser logPrefix],
|
|
colNumber,
|
|
lineNumber,
|
|
message];
|
|
};
|
|
|
|
@end
|
|
|
|
//====================================================================
|
|
@implementation GSWTemplateParserXML
|
|
|
|
//--------------------------------------------------------------------
|
|
-(void)dealloc
|
|
{
|
|
DESTROY(_xmlDocument);
|
|
[super dealloc];
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
static NSString* TabsForLevel(int level)
|
|
{
|
|
int i=0;
|
|
NSMutableString* tabs=[NSMutableString string];
|
|
for (i=0;i<level;i++)
|
|
{
|
|
[tabs appendString:@"\t"];
|
|
};
|
|
return tabs;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
-(NSString*)dumpNode:(GSXMLNode*)node
|
|
atLevel:(int)level
|
|
{
|
|
NSString* dumpString=[NSString string];
|
|
LOGObjectFnStart();
|
|
while (node)
|
|
{
|
|
const char* content=[[node content] lossyCString];
|
|
dumpString=[dumpString stringByAppendingFormat:@"%@%@ [Type:%@] [%@]%s%s\n",
|
|
TabsForLevel(level),
|
|
[node name],
|
|
[node typeDescription],
|
|
[node propertiesAsDictionary],
|
|
(content ? ":\n" : ""),
|
|
(content ? content : "")];
|
|
if ([node children])
|
|
dumpString=[dumpString stringByAppendingString:[self dumpNode:[node children]
|
|
atLevel:level+1]];
|
|
node=[node next];
|
|
};
|
|
LOGObjectFnStop();
|
|
return dumpString;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
-(NSArray*)templateElements
|
|
{
|
|
NSArray* elements=nil;
|
|
LOGObjectFnStart();
|
|
if (!_xmlDocument)
|
|
{
|
|
BOOL parseOk=NO;
|
|
GSXMLParser* parser=nil;
|
|
GSWTemplateParserSAXHandler* sax=nil;
|
|
NSStringEncoding stringEncoding=_stringEncoding;
|
|
|
|
if (stringEncoding==GSUndefinedEncoding)
|
|
stringEncoding=NSISOLatin1StringEncoding;
|
|
|
|
sax=[GSWTemplateParserSAXHandler handlerWithTemplateParser:self];
|
|
if ([self isKindOfClass:[GSWTemplateParserXMLHTML class]])
|
|
{
|
|
NSRange tagRange=NSMakeRange(NSNotFound,0);
|
|
tagRange=[_string rangeOfString:@"<HTML"
|
|
options:NSCaseInsensitiveSearch];
|
|
//NSDebugMLog(@"HTML Tag Range length=%d",tagRange.length);
|
|
if (tagRange.length>0)
|
|
_isHTMLTag=YES;
|
|
tagRange=[_string rangeOfString:@"<BODY"
|
|
options:NSCaseInsensitiveSearch];
|
|
//NSDebugMLog(@"BODY Tag Range length=%d",tagRange.length);
|
|
if (tagRange.length>0)
|
|
_isBodyTag=YES;
|
|
parser=[GSHTMLParser parserWithSAXHandler:sax
|
|
withData:[_string dataUsingEncoding:stringEncoding]];
|
|
}
|
|
else
|
|
{
|
|
NSString* xmlHeader=nil;
|
|
NSRange docTypeRange=NSMakeRange(NSNotFound,0);
|
|
NSString* stringToParse=nil;
|
|
NSString* encodingString=nil;
|
|
encodingString=[GSXMLParser xmlEncodingStringForStringEncoding:stringEncoding];
|
|
if (encodingString)
|
|
encodingString=[NSString stringWithFormat:@" encoding=\"%@\"",encodingString];
|
|
else
|
|
encodingString=@"";
|
|
xmlHeader=[NSString stringWithFormat:@"<?xml version=\"%@\"%@?>\n",
|
|
@"1.0",
|
|
encodingString];
|
|
docTypeRange=[_string rangeOfString:@"<!DOCTYPE"];
|
|
if (docTypeRange.length==0)
|
|
stringToParse=[@"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"xhtml1-transitional.dtd\">\n" stringByAppendingString:_string];
|
|
else
|
|
stringToParse=_string;
|
|
stringToParse=[xmlHeader stringByAppendingString:stringToParse];
|
|
NSLog(@"stringToParse=%@",stringToParse);
|
|
parser=[GSXMLParser parserWithSAXHandler:sax
|
|
withData:[stringToParse dataUsingEncoding:stringEncoding]];
|
|
};
|
|
[parser doValidityChecking:YES];
|
|
[parser getWarnings:YES];
|
|
//[parser setExternalEntityLoader:GSWTemplateParserSAXHandler_ExternalLoader];
|
|
NS_DURING
|
|
{
|
|
parseOk=[parser parse];
|
|
}
|
|
NS_HANDLER
|
|
{
|
|
LOGError(@"%@ Exception in parse! Exception: %@",
|
|
[self logPrefix],
|
|
localException);
|
|
localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
|
|
@"%@ - In [parser parse] Exception!",
|
|
[self logPrefix]);
|
|
[localException retain];
|
|
[localException autorelease];
|
|
[localException raise];
|
|
}
|
|
NS_ENDHANDLER;
|
|
if (!parseOk)
|
|
{
|
|
NSDebugMLog(@"######Parse FAILED errNo=%d [parser doc]=%p",
|
|
[parser errNo],
|
|
[parser doc]);
|
|
// May be validity errors only (like no HTML root)
|
|
if ([parser doc])
|
|
parseOk=YES;
|
|
};
|
|
if (parseOk)
|
|
{
|
|
GSXMLNode* node=nil;
|
|
NSDebugMLog(@"Root");
|
|
ASSIGN(_xmlDocument,[parser doc]);
|
|
node=[_xmlDocument root];
|
|
NSAssert1(node,@"%@ Empty Document (root)",
|
|
[self logPrefix]);
|
|
#ifndef NDEBUG
|
|
{
|
|
NSString* dumpString=[self dumpNode:node
|
|
atLevel:0];
|
|
NSDebugMLLog0(@"low",@"Will dump _xmlDocument");
|
|
NSDebugMLLog(@"low",@"%@ _xmlDocument=\n%@",
|
|
[self logPrefix],
|
|
dumpString);
|
|
NSDebugMLLog0(@"low",@"_xmlDocument dumped");
|
|
};
|
|
#endif
|
|
/* if (node->type!=XML_DTD_NODE)
|
|
{
|
|
NSLog(@"Bad first node type: %@ instead of %@",
|
|
[nodeTypes objectForKey:[NSString stringWithFormat:@"%d",(int)node->type]],
|
|
[nodeTypes objectForKey:[NSString stringWithFormat:@"%d",(int)XML_DTD_NODE]]);
|
|
};
|
|
*/
|
|
// NSDebugMLog(@"Test Root");
|
|
if ([node type]!=XML_ELEMENT_NODE)
|
|
node=[node children];
|
|
// NSDebugMLog(@"Test Root children");
|
|
NSAssert1(node,@"%@ Empty Document ([root children])",
|
|
[self logPrefix]);
|
|
if ([node type]!=XML_ELEMENT_NODE)
|
|
node=[node next];
|
|
// NSDebugMLog(@"Test Root children Next");
|
|
NSAssert1(node,@"%@ Empty Document ([[root children] next])",
|
|
[self logPrefix]);
|
|
//Remove html and body node when they have been added by html parser
|
|
if (!_isHTMLTag || !_isBodyTag)
|
|
{
|
|
BOOL cont=YES;
|
|
while (node && cont)
|
|
{
|
|
cont=NO;
|
|
if ([node type]==XML_ELEMENT_NODE)
|
|
{
|
|
NSString* nodeName=[node name];
|
|
//NSDebugMLog(@"node name=%@",nodeName);
|
|
/*NSDebugMLog(@"_isHTMLTag=%s _isBodyTag=%s",
|
|
(_isHTMLTag ? "YES" : "NO"),
|
|
(_isBodyTag ? "YES" : "NO"));
|
|
*/
|
|
if ((!_isHTMLTag && [nodeName caseInsensitiveCompare:@"html"]==NSOrderedSame)
|
|
|| (!_isBodyTag && [nodeName caseInsensitiveCompare:@"body"]==NSOrderedSame))
|
|
{
|
|
//NSDebugMLog(@"==> Children");
|
|
node=[node children];
|
|
cont=YES;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
if (node)
|
|
{
|
|
//NSDebugMLog(@"Call createElementsFromNode:");
|
|
NS_DURING
|
|
{
|
|
gswebTagN=0;
|
|
tagN=0;
|
|
elements=[self createElementsFromNode:node];
|
|
}
|
|
NS_HANDLER
|
|
{
|
|
LOGError(@"%@ Exception in elements creation!",
|
|
[self logPrefix]);
|
|
localException=ExceptionByAddingUserInfoObjectFrameInfo(localException,
|
|
@"%@ - Exception in elements creation",
|
|
[self logPrefix]);
|
|
[localException retain];
|
|
[localException autorelease];
|
|
[localException raise];
|
|
}
|
|
NS_ENDHANDLER;
|
|
};
|
|
};
|
|
};
|
|
LOGObjectFnStop();
|
|
return elements;
|
|
};
|
|
|
|
//--------------------------------------------------------------------
|
|
|
|
/*
|
|
text [Type:XML_TEXT_NODE] [{}] ####
|
|
head [Type:XML_ELEMENT_NODE] [{}] ##(null)##
|
|
title [Type:XML_ELEMENT_NODE] [{}] ##(null)##
|
|
text [Type:XML_TEXT_NODE] [{}] ##MyTitle##
|
|
text [Type:XML_TEXT_NODE] [{}] ####
|
|
body [Type:XML_ELEMENT_NODE] [{bgcolor = white; }] ##(null)##
|
|
text [Type:XML_TEXT_NODE] [{}] ####
|
|
gsweb [Type:XML_ELEMENT_NODE] [{name = MyObject; }] ##(null)##
|
|
text [Type:XML_TEXT_NODE] [{}] ##AText##
|
|
p [Type:XML_ELEMENT_NODE] [{align = center; }] ##(null)##
|
|
text [Type:XML_TEXT_NODE] [{}] ##Text2##
|
|
b [Type:XML_ELEMENT_NODE] [{}] ##(null)##
|
|
text [Type:XML_TEXT_NODE] [{}] ##Text3##
|
|
text [Type:XML_TEXT_NODE] [{}] ####
|
|
text [Type:XML_TEXT_NODE] [{}] ##TEXTB##
|
|
comment [Type:XML_COMMENT_NODE] [{}] ##MyComment##
|
|
text [Type:XML_TEXT_NODE] [{}] ##TEXTC##
|
|
text [Type:XML_TEXT_NODE] [{}] ####
|
|
*/
|
|
-(NSArray*)createElementsFromNode:(GSXMLNode*)node
|
|
{
|
|
GSXMLNode* currentNode=node;
|
|
NSMutableArray* _elements=nil;
|
|
NSAutoreleasePool* arp = nil;
|
|
LOGObjectFnStart();
|
|
_elements=[NSMutableArray array];
|
|
arp=[NSAutoreleasePool new];
|
|
while(currentNode)
|
|
{
|
|
GSWElement* elem=nil;
|
|
NSDebugMLog(@"BEGIN node=%p %@ [Type:%@] [%@] ##%s##\n",
|
|
currentNode,
|
|
[currentNode name],
|
|
[currentNode typeDescription],
|
|
[currentNode propertiesAsDictionary],
|
|
[[currentNode content] lossyCString]);
|
|
switch([currentNode type])
|
|
{
|
|
case XML_TEXT_NODE:
|
|
{
|
|
NSDebugMLog0(@"TEXT");
|
|
elem=[GSWHTMLBareString elementWithString:
|
|
[NSString stringWithCString:
|
|
[[[currentNode content]
|
|
stringByConvertingToHTMLEntities]
|
|
lossyCString]]];//Because XML Parser decode characters
|
|
NSDebugMLog(@"TEXT element=%@",elem);
|
|
};
|
|
break;
|
|
case XML_CDATA_SECTION_NODE:
|
|
{
|
|
NSDebugMLog0(@"CDATA_SECTION");
|
|
elem=[GSWHTMLBareString elementWithString:[currentNode content]];
|
|
NSDebugMLog(@"TEXT element=%@",elem);
|
|
};
|
|
break;
|
|
case XML_COMMENT_NODE:
|
|
{
|
|
NSDebugMLog0(@"COMMENT");
|
|
elem=[GSWHTMLBareString elementWithString:[NSString stringWithFormat:@"<!-- %s -->",[[currentNode content] lossyCString]]];
|
|
NSDebugMLog(@"COMMENT element=%@",elem);
|
|
};
|
|
break;
|
|
default:
|
|
{
|
|
int currentGSWebTagN=0;
|
|
int currentTagN=0;
|
|
NSArray* children=nil;
|
|
NSDictionary* nodeAttributes=nil;
|
|
NSString* nodeName=nil;
|
|
NSString* nodeNameAttribute=nil;
|
|
nodeName=[currentNode name];
|
|
NSDebugMLog(@"DEFAULT (name=%@ type=%@)",nodeName,[currentNode typeDescription]);
|
|
//if (currentNode->type==XML_ELEMENT_NODE)
|
|
{
|
|
nodeAttributes=[currentNode propertiesAsDictionaryWithKeyTransformationSel:@selector(lowercaseString)];
|
|
nodeNameAttribute=[nodeAttributes objectForKey:@"name"];
|
|
NSDebugMLog(@"node=%p nodeAttributes=%@",currentNode,nodeAttributes);
|
|
NSDebugMLog(@"node=%p nodeNameAttribute=%@",currentNode,nodeNameAttribute);
|
|
tagN++;
|
|
if ([nodeName caseInsensitiveCompare:GSWTag_Name[GSWNAMES_INDEX]]==NSOrderedSame
|
|
||[nodeName caseInsensitiveCompare:GSWTag_Name[WONAMES_INDEX]]==NSOrderedSame)
|
|
gswebTagN++;
|
|
currentGSWebTagN=gswebTagN;
|
|
currentTagN=tagN;
|
|
if ([currentNode children])
|
|
{
|
|
children=[self createElementsFromNode:[currentNode children]];
|
|
NSDebugMLog(@"node=%p children=%@",currentNode,children);
|
|
};
|
|
if ([nodeName caseInsensitiveCompare:GSWTag_Name[GSWNAMES_INDEX]]==NSOrderedSame
|
|
||[nodeName caseInsensitiveCompare:GSWTag_Name[WONAMES_INDEX]]==NSOrderedSame)
|
|
{
|
|
GSWPageDefElement* definitionsElement=nil;
|
|
if (!nodeNameAttribute)
|
|
{
|
|
ExceptionRaise(@"GSWTemplateParser",
|
|
@"%@ No element name for gsweb tag (%@) [#%d,#%d]",
|
|
[self logPrefix],
|
|
nodeName,
|
|
currentGSWebTagN,
|
|
currentTagN);
|
|
}
|
|
else
|
|
{
|
|
definitionsElement=[_definitions objectForKey:nodeNameAttribute];
|
|
NSDebugMLLog(@"low",@"definitionsElement:[%@]",
|
|
definitionsElement);
|
|
NSDebugMLLog(@"low",@"GSWeb Tag definitionsElement:[%@]",
|
|
definitionsElement);
|
|
if (!definitionsElement)
|
|
{
|
|
ExceptionRaise(@"GSWTemplateParser",
|
|
@"%@ No element definition for tag named:%@ [#%d,#%d]",
|
|
[self logPrefix],
|
|
nodeNameAttribute,
|
|
currentGSWebTagN,
|
|
currentTagN);
|
|
}
|
|
else
|
|
{
|
|
NSDictionary* _associations=[definitionsElement associations];
|
|
NSString* className=[definitionsElement className];
|
|
NSDebugMLLog(@"low",@"node=%p GSWeb Tag className:[%@]",currentNode,className);
|
|
if (!className)
|
|
{
|
|
ExceptionRaise(@"GSWTemplateParser",
|
|
@"%@No class name in page definition for tag named:%@ definitionsElement=%@ [#%d,#%d]",
|
|
[self logPrefix],
|
|
nodeNameAttribute,
|
|
definitionsElement,
|
|
currentGSWebTagN,
|
|
currentTagN);
|
|
}
|
|
else
|
|
{
|
|
NSDebugMLLog(@"low",@"node=%p associations:%@",currentNode,_associations);
|
|
{
|
|
NSEnumerator* _nodeAttributesEnum = [nodeAttributes keyEnumerator];
|
|
id _tagAttrKey=nil;
|
|
id _tagAttrValue=nil;
|
|
NSMutableDictionary* _addedAssoc=nil;
|
|
while ((_tagAttrKey = [_nodeAttributesEnum nextObject]))
|
|
{
|
|
if (![_tagAttrKey isEqualToString:@"name"] && ![_associations objectForKey:_tagAttrKey])
|
|
{
|
|
if (!_addedAssoc)
|
|
_addedAssoc=(NSMutableDictionary*)[NSMutableDictionary dictionary];
|
|
_tagAttrValue=[nodeAttributes objectForKey:_tagAttrKey];
|
|
[_addedAssoc setObject:[GSWAssociation associationWithValue:_tagAttrValue]
|
|
forKey:_tagAttrKey];
|
|
};
|
|
};
|
|
if (_addedAssoc)
|
|
{
|
|
_associations=[_associations dictionaryByAddingEntriesFromDictionary:_addedAssoc];
|
|
};
|
|
};
|
|
NSDebugMLog(@"node=%p gsweb name=%@ dynamicElementWithName: children=%@",
|
|
currentNode,
|
|
nodeNameAttribute,
|
|
children);
|
|
NSDebugMLog(@"node=%p %@ [Type:%@] [%@] ##%s##\n",
|
|
currentNode,
|
|
[currentNode name],
|
|
[currentNode typeDescription],
|
|
[currentNode propertiesAsDictionary],
|
|
[[currentNode content] lossyCString]);
|
|
elem=[GSWApp dynamicElementWithName:className
|
|
associations:_associations
|
|
template:[[[GSWHTMLStaticGroup alloc]initWithContentElements:children]autorelease]
|
|
languages:_languages];
|
|
NSDebugMLog(@"node=%p element=%@",currentNode,elem);
|
|
if (!elem)
|
|
{
|
|
ExceptionRaise(@"GSWTemplateParser",
|
|
@"%@ Creation failed for element named:%@ className:%@",
|
|
[self logPrefix],
|
|
[definitionsElement elementName],
|
|
className);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|
|
else
|
|
{
|
|
//It's a hack to remove html & body elements where there's not in the template (HTML parser add them when there are missing)
|
|
if ((!_isHTMLTag
|
|
&& [nodeName caseInsensitiveCompare:@"html"]==NSOrderedSame
|
|
&& [nodeAttributes count]==0)
|
|
|| (!_isBodyTag
|
|
&& [nodeName caseInsensitiveCompare:@"body"]==NSOrderedSame
|
|
&& [nodeAttributes count]==0))
|
|
{
|
|
NSDebugMLog(@"node=%p StaticElement: children=%@",currentNode,children);
|
|
elem=[[[GSWHTMLStaticElement alloc]initWithName:nil
|
|
attributeDictionary:nil
|
|
contentElements:children]autorelease];
|
|
NSDebugMLog(@"node=%p element=%@",currentNode,elem);
|
|
}
|
|
else
|
|
{
|
|
NSDictionary* _associations=nil;
|
|
NSEnumerator* _nodeAttributesEnum = [nodeAttributes keyEnumerator];
|
|
id _tagAttrKey=nil;
|
|
id _tagAttrValue=nil;
|
|
NSMutableDictionary* _addedAssoc=nil;
|
|
NSDebugMLog(@"node=%p Create nodeName=%@",currentNode,nodeName);
|
|
while ((_tagAttrKey = [_nodeAttributesEnum nextObject]))
|
|
{
|
|
if (![_tagAttrKey isEqualToString:@"name"] && ![_associations objectForKey:_tagAttrKey])
|
|
{
|
|
if (!_addedAssoc)
|
|
_addedAssoc=(NSMutableDictionary*)[NSMutableDictionary dictionary];
|
|
_tagAttrValue=[nodeAttributes objectForKey:_tagAttrKey];
|
|
[_addedAssoc setObject:[GSWAssociation associationWithValue:_tagAttrValue]
|
|
forKey:_tagAttrKey];
|
|
};
|
|
};
|
|
if (_addedAssoc)
|
|
{
|
|
_associations=[NSDictionary dictionaryWithDictionary:_addedAssoc];
|
|
};
|
|
NSDebugMLog(@"node=%p StaticElement: children=%@",currentNode,children);
|
|
elem=[[[GSWHTMLStaticElement alloc]initWithName:nodeName
|
|
attributeDictionary:_associations
|
|
contentElements:children]autorelease];
|
|
NSDebugMLog(@"node=%p element=%@",currentNode,elem);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
break;
|
|
};
|
|
[_elements addObject:elem];
|
|
NSDebugMLog(@"END node=%p %@ [Type:%@] [%@] ##%s##\n",
|
|
currentNode,
|
|
[currentNode name],
|
|
[currentNode typeDescription],
|
|
[currentNode propertiesAsDictionary],
|
|
[[currentNode content] lossyCString]);
|
|
currentNode=[currentNode next];
|
|
};
|
|
DESTROY(arp);
|
|
LOGObjectFnStop();
|
|
NSDebugMLog(@"_elements=%@",_elements);
|
|
return _elements;
|
|
};
|
|
|
|
@end
|
|
|
|
|
|
//====================================================================
|
|
// used only for XML/XMLHTML differences
|
|
@implementation GSWTemplateParserXMLHTML
|
|
|
|
@end
|