2002-09-12 Manuel Guesdon <mguesdon@orange-concept.com>

o added -setNoOmittedTags:
		o changes in xml parsing calls
		o allow null name gsweb/webobjects tags


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gsweb/trunk@14734 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Manuel Guesdon 2002-10-12 11:21:34 +00:00
parent 9d00150ed4
commit e2dcd26d17

View file

@ -39,6 +39,7 @@ extern xmlParserInputPtr xmlNewStringInputStream(xmlParserCtxtPtr ctxt,
static NSLock* GSXMLParserLock=nil; static NSLock* GSXMLParserLock=nil;
static NSMutableDictionary* DTDCache=nil; static NSMutableDictionary* DTDCache=nil;
static NSMutableDictionary* DTDFilePathCache=nil;
//==================================================================== //====================================================================
@implementation GSWTemplateParserSAXHandler @implementation GSWTemplateParserSAXHandler
@ -51,6 +52,8 @@ static NSMutableDictionary* DTDCache=nil;
{ {
if (!DTDCache) if (!DTDCache)
DTDCache=[NSMutableDictionary new]; DTDCache=[NSMutableDictionary new];
if (!DTDFilePathCache)
DTDFilePathCache=[NSMutableDictionary new];
if (!GSXMLParserLock) if (!GSXMLParserLock)
GSXMLParserLock=[NSRecursiveLock new]; GSXMLParserLock=[NSRecursiveLock new];
}; };
@ -63,6 +66,7 @@ static NSMutableDictionary* DTDCache=nil;
if (self==[GSWTemplateParserSAXHandler class]) if (self==[GSWTemplateParserSAXHandler class])
{ {
DESTROY(DTDCache); DESTROY(DTDCache);
DESTROY(DTDFilePathCache);
DESTROY(GSXMLParserLock); DESTROY(GSXMLParserLock);
}; };
}; };
@ -100,7 +104,7 @@ static NSMutableDictionary* DTDCache=nil;
}; };
//-------------------------------------------------------------------- //--------------------------------------------------------------------
/*"Find cached DTD Content for Key url"*/ /** Find cached DTD Content for Key url **/
+(NSString*)cachedDTDContentForKey:(NSString*)url +(NSString*)cachedDTDContentForKey:(NSString*)url
{ {
NSString* content=nil; NSString* content=nil;
@ -111,7 +115,7 @@ static NSMutableDictionary* DTDCache=nil;
}; };
//-------------------------------------------------------------------- //--------------------------------------------------------------------
/*"Cache DTD Content externalContent for Key url"*/ /** Cache DTD Content externalContent for Key url **/
+(void)setCachedDTDContent:(NSString*)externalContent +(void)setCachedDTDContent:(NSString*)externalContent
forKey:(NSString*)url forKey:(NSString*)url
{ {
@ -121,6 +125,28 @@ static NSMutableDictionary* DTDCache=nil;
[self unlock]; [self unlock];
}; };
//--------------------------------------------------------------------
/** Find cached DTD FilePath for Key url **/
+(NSString*)cachedDTDFilePathForKey:(NSString*)url
{
NSString* filePath=nil;
[self lock];
filePath=[DTDFilePathCache objectForKey:url];
[self unlock];
return filePath;
};
//--------------------------------------------------------------------
/** Cache DTD FilePath for Key url **/
+(void)setCachedDTDFilePath:(NSString*)filePath
forKey:(NSString*)url
{
[self lock];
[DTDFilePathCache setObject:filePath
forKey:url];
[self unlock];
};
//-------------------------------------------------------------------- //--------------------------------------------------------------------
+(id)handlerWithTemplateParser:(GSWTemplateParser*)templateParser +(id)handlerWithTemplateParser:(GSWTemplateParser*)templateParser
{ {
@ -185,6 +211,144 @@ extern void externalSubset (void *ctx,
return self; return self;
}; };
+ (NSString*) loadEntity: (NSString*)publicId
at: (NSString*)location
{
NSDebugMLog(@"+LOAD ENTITY pid=%@ l=%@",publicId,location);
return nil;
}
/** Should return a file path
publicId: for exemple: -//W3C//DTD XHTML 1.0 Transitional//EN
location: for exemple: xhtml1-transitional.dtd
**/
- (NSString*) loadEntity: (NSString*)publicId
at: (NSString*)location
{
NSString* filePath=nil;
LOGObjectFnStart();
NSDebugMLLog(@"GSWTemplateParser",@"loadEntity:%@ at:%@\n",
publicId,
location);
NSAssert(publicId || location,
@"resolveEntity: publicId and location are both nil");
if (location)
{
NSString* resourceName=location;
if ([[resourceName pathExtension] isEqual:@"dtd"])
resourceName=[resourceName stringByDeletingPathExtension];
filePath = [[NSBundle bundleForClass: [self class]]
pathForResource:resourceName
ofType:@"dtd"
inDirectory:@"DTDs"];
NSDebugMLLog(@"GSWTemplateParser",@"location: fileName=%@ for Resource:%@",filePath,resourceName);
};
if (!filePath && publicId)
{
filePath=[[self class] cachedDTDFilePathForKey:publicId];
if (!filePath)
{
//Well Known DTDs / Entities
if ([publicId hasPrefix:@"-//"])
{
// 0: -
// 1: W3C or IETF
// 2: DTD ... or ENTITIES ...
// 3: EN or ... (language)
NSArray* parts=[publicId componentsSeparatedByString:@"//"];
if ([parts count]>=2)
{
NSString* whatPart=[parts objectAtIndex:2];
if ([whatPart hasPrefix:@"DTD"])
{
NSString* resourceName=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
{
NSDebugMLog(@"Unknown DTD: %@. Choose default: xhtml1-transitional.dtd",publicId);
resourceName=@"xhtml1-transitional.dtd"; // guess
};
if (resourceName)
{
if ([[resourceName pathExtension] isEqual:@"dtd"])
resourceName=[resourceName stringByDeletingPathExtension];
filePath = [[NSBundle bundleForClass: [self class]]
pathForResource:resourceName
ofType:@"dtd"
inDirectory:@"DTDs"];
NSDebugMLLog(@"GSWTemplateParser",@"fileName=%@ for Resource:%@",filePath,publicId);
};
}
else if ([whatPart hasPrefix:@"ENTITIES"])
{
NSString* resourceName=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
{
NSDebugMLog(@"Unknown ENTITIES: %@",publicId);
};
if (resourceName)
{
if ([[resourceName pathExtension] isEqual:@"ent"])
resourceName=[resourceName stringByDeletingPathExtension];
filePath = [[NSBundle bundleForClass: [self class]]
pathForResource:resourceName
ofType:@"ent"
inDirectory:@"DTDs"];
NSDebugMLLog(@"GSWTemplateParser",@"fileName=%@ for Resource:%@",filePath,publicId);
};
}
else
{
NSDebugMLog(@"Unknown publicId %@",publicId);
};
}
else
{
NSDebugMLog(@"Don't know how to parse publicId %@",publicId);
};
}
else
{
NSDebugMLog(@"Don't know what to do with publicId %@",publicId);
};
if (filePath)
[[self class] setCachedDTDFilePath:filePath
forKey:publicId];
};
};
if (!filePath)
{
NSDebugMLog(@"Can't load external (publicId:%@ location:%@)",publicId,location);
}
else
{
NSDebugMLLog(@"GSWTemplateParser",@"LOADED: resolveEntity:%@ location:%@ filePath:%@\n",
publicId,
location,
filePath);
};
LOGObjectFnStop();
return filePath;
}
- (void*) getEntity: (NSString*)name
{
NSDebugMLog(@"-GET ENTITY %@",name);
return 0;
}
/* /*
xmlParserInputPtr GSWTemplateParserSAXHandler_ExternalLoader(const char *systemId, xmlParserInputPtr GSWTemplateParserSAXHandler_ExternalLoader(const char *systemId,
const char *publicId, const char *publicId,
@ -497,6 +661,7 @@ static NSString* TabsForLevel(int level)
} }
else else
{ {
NSData* dataToParse=nil;
NSString* xmlHeader=nil; NSString* xmlHeader=nil;
NSRange docTypeRange=NSMakeRange(NSNotFound,0); NSRange docTypeRange=NSMakeRange(NSNotFound,0);
NSString* stringToParse=nil; NSString* stringToParse=nil;
@ -506,17 +671,29 @@ static NSString* TabsForLevel(int level)
encodingString=[NSString stringWithFormat:@" encoding=\"%@\"",encodingString]; encodingString=[NSString stringWithFormat:@" encoding=\"%@\"",encodingString];
else else
encodingString=@""; encodingString=@"";
stringToParse=_string;
// Add a <gsweb> null tag around the code because libxml parser doesn't support <tag>..</tag><tag>..</tag>...
stringToParse=[NSString stringWithFormat:@"<gsweb>\n%@\n</gsweb>\n",stringToParse];
// Build the header
xmlHeader=[NSString stringWithFormat:@"<?xml version=\"%@\"%@?>\n", xmlHeader=[NSString stringWithFormat:@"<?xml version=\"%@\"%@?>\n",
@"1.0", @"1.0",
encodingString]; encodingString];
docTypeRange=[_string rangeOfString:@"<!DOCTYPE"];
if (docTypeRange.length==0) /* Don't care about DOCTYPE !
stringToParse=[@"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"xhtml1-transitional.dtd\">\n" stringByAppendingString:_string]; docTypeRange=[stringToParse rangeOfString:@"<!DOCTYPE"];
else if (docTypeRange.length==0)
stringToParse=_string; stringToParse=[@"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"xhtml1-transitional.dtd\">\n"
stringByAppendingString:stringToParse];
*/
stringToParse=[xmlHeader stringByAppendingString:stringToParse]; stringToParse=[xmlHeader stringByAppendingString:stringToParse];
NSDebugMLog(@"stringToParse (%d)=%@",[stringToParse length],stringToParse);
dataToParse=[stringToParse dataUsingEncoding:stringEncoding];
parser=[GSXMLParser parserWithSAXHandler:sax parser=[GSXMLParser parserWithSAXHandler:sax
withData:[stringToParse dataUsingEncoding:stringEncoding]]; withData:dataToParse];
[parser keepBlanks:YES];
}; };
[parser doValidityChecking:YES]; [parser doValidityChecking:YES];
[parser getWarnings:YES]; [parser getWarnings:YES];
@ -540,9 +717,20 @@ static NSString* TabsForLevel(int level)
NS_ENDHANDLER; NS_ENDHANDLER;
if (!parseOk) if (!parseOk)
{ {
NSDebugMLLog(@"GSWTemplateParser",@"######Parse FAILED errNo=%d [parser document]=%p", int errNo=[parser errNo];
[parser errNo], // We point out only deep error
[parser document]); switch(errNo)
{
case XML_ERR_NO_DTD:
NSDebugMLLog(@"GSWTemplateParser",@"%@ - Warning: No DTD",
[self logPrefix]);
break;
default:
NSDebugMLLog(@"GSWTemplateParser",@"######Parse FAILED errNo=%d [parser document]=%p",
[parser errNo],
[parser document]);
break;
};
// May be validity errors only (like no HTML root) // May be validity errors only (like no HTML root)
if ([parser document]) if ([parser document])
parseOk=YES; parseOk=YES;
@ -768,12 +956,15 @@ text [Type:XML_TEXT_NODE] [{}] ####
GSWPageDefElement* definitionsElement=nil; GSWPageDefElement* definitionsElement=nil;
if (!nodeNameAttribute) if (!nodeNameAttribute)
{ {
ExceptionRaise(@"GSWTemplateParser", // allow null name tags
elem=[[[GSWHTMLStaticGroup alloc]initWithContentElements:children]autorelease];
/* ExceptionRaise(@"GSWTemplateParser",
@"%@ No element name for gsweb tag (%@) [#%d,#%d]", @"%@ No element name for gsweb tag (%@) [#%d,#%d]",
[self logPrefix], [self logPrefix],
nodeName, nodeName,
currentGSWebTagN, currentGSWebTagN,
currentTagN); currentTagN);
*/
} }
else else
{ {
@ -923,7 +1114,7 @@ text [Type:XML_TEXT_NODE] [{}] ####
}; };
break; break;
}; };
if (elem) if (elem)
[_elements addObject:elem]; [_elements addObject:elem];
NSDebugMLLog(@"GSWTemplateParser",@"END node=%p %@ [Type:%@] [%@] ##%s##\n", NSDebugMLLog(@"GSWTemplateParser",@"END node=%p %@ [Type:%@] [%@] ##%s##\n",
currentNode, currentNode,
@ -946,5 +1137,11 @@ text [Type:XML_TEXT_NODE] [{}] ####
// used only for XML/XMLHTML differences // used only for XML/XMLHTML differences
@implementation GSWTemplateParserXMLHTML @implementation GSWTemplateParserXMLHTML
/** call htmlHandleOmittedElem(0) if YES, htmlHandleOmittedElem(1) if NO; **/
-(void)setNoOmittedTags:(BOOL)yn
{
htmlHandleOmittedElem(yn ? 0 : 1);
};
@end @end