From 49145455083d76133893cb2e79c842311266731c Mon Sep 17 00:00:00 2001 From: Dave Ward Date: Mon, 27 Sep 2010 12:47:35 +0000 Subject: [PATCH] =?UTF-8?q?Merged=20V3.3-BUG-FIX=20to=20HEAD=20=20=20=2022?= =?UTF-8?q?215:=20Fix=20compilation=20error=20=20=20=2022240:=20ALF-4207:?= =?UTF-8?q?=20Download=20servlets=20show=20error=20page=20with=20permissio?= =?UTF-8?q?ns=20error=20rather=20than=20login=20page=20when=20non-guest=20?= =?UTF-8?q?user=20has=20insufficient=20permissions=20=20=20=2022241:=20ALF?= =?UTF-8?q?-4469:=20External=20Access=20Servlet=20should=20also=20show=20s?= =?UTF-8?q?tatus=20403=20errors=20to=20non-guest=20users,=20as=20in=20ALF-?= =?UTF-8?q?4207=20=20=20=2022244:=20ALF-4599:=20CIFS=20access=20to=20alfre?= =?UTF-8?q?sco=20with=20Kerberos=20authentication=20creates=20wrong=20user?= =?UTF-8?q?s=20with=20domain=20suffix=20=20=20=20=20=20=20ALF-4395:=20reco?= =?UTF-8?q?gnize=20Kerberos=20machine=20accounts=20with=20lower=20case=20n?= =?UTF-8?q?ames=20=20=20=2022247:=20ALF-4397:=20Properly=20handle=20null?= =?UTF-8?q?=20values=20in=20SortableSelectItem.compareTo()=20=20=20=202224?= =?UTF-8?q?8:=20Merged=20DEV/TEMPORARY=20to=20V3.3-BUG-FIX=20=20=20=20=20?= =?UTF-8?q?=20=2021963:=20ALF-4390:=20ModuleManagementTool=20is=20not=20re?= =?UTF-8?q?turning=20error=20code=20in=20case=20of=20failure=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20Error=20code=20constants=20and=20appropriate?= =?UTF-8?q?=20System.exit(code)=20invokations=20were=20added.=20=20=20=202?= =?UTF-8?q?2260:=20ALF-4597:=20InviteContentUsersWizard=20was=20caching=20?= =?UTF-8?q?permissions=20in=20a=20non-type-specific=20cache=20=20=20=20=20?= =?UTF-8?q?=20=20-=20removed=20the=20cache=20-=20didn't=20allow=20for=20dy?= =?UTF-8?q?namic=20model=20updates=20either=20=20=20=2022269:=20Merged=20V?= =?UTF-8?q?3.3=20to=20V3.3-BUG-FIX=20(RECORD=20ONLY)=20=20=20=20=20=20=202?= =?UTF-8?q?2268:=20Merged=20V3.3-BUG-FIX=20to=20V3.3=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20-=20Merged=20across=20all=20differences=20from=20V3.3-?= =?UTF-8?q?BUG-FIX=20=20=20=2022270:=20Incremented=20revision=20number=20?= =?UTF-8?q?=20=20=2022467:=20Merge=20from=20V3.3=20to=20V3.3BUG-FIX.=20Fix?= =?UTF-8?q?=20for=20ALF-4741.=20=20=20=20=20=20=20V3.3:=2022466=20Merge=20?= =?UTF-8?q?from=20V3.2=20to=20V3.3.=20Fix=20for=20ALF-4741.=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20V3.2:=2022465=20Fix=20for=20ALF-4741.=20Reposito?= =?UTF-8?q?ry=20Web=20Scripts=20can=20produce=20a=20corrupted=20response?= =?UTF-8?q?=20after=20a=20transaction=20collision/retry.=20=20=20=2022667:?= =?UTF-8?q?=20Merged=20DEV/TEMPORARY=20to=20V3.3-BUG-FIX=20=20=20=20=20=20?= =?UTF-8?q?=2022665:=20ALF-4825:=20Unlocking=20checked=20out=20content=20c?= =?UTF-8?q?ause=20both=20original=20&=20working=20copy=20un-usable.=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20Do=20not=20include=20unlock=20in=20the?= =?UTF-8?q?=20actions=20list=20when=20a=20node=20has=20a=20working=20copy.?= =?UTF-8?q?=20=20=20=2022691:=20Add=20missing=20"logAbandoned"=20(=3D=20fa?= =?UTF-8?q?lse)=20prop=20to=20config=20-=20follow=20on=20to=20r15133=20(re?= =?UTF-8?q?lated=20to=20ALF-4020=20/=20ETWOTWO-562)=20=20=20=2022710:=20AL?= =?UTF-8?q?F-3948=20-=20from=20time=20to=20time=20we=20have=20exception=20?= =?UTF-8?q?"Failed=20to=20init=20dictionaryRegistry"=20=20=20=2022718:=20M?= =?UTF-8?q?erge=20from=20V3.3=20to=20V3.3-BUG-FIX=20=20=20=20=20=20=20r=20?= =?UTF-8?q?22715=20Merge=20from=20V3.2=20to=20V3.3=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20r=2022713=20Fix=20for=20ALF-4946=20Possible=20NullPointer?= =?UTF-8?q?Exception=20during=20creation=20of=20thumbnails=20whose=20names?= =?UTF-8?q?=20are=20null-valued.=20=20=20=2022722:=20Merged=20V3.3=20to=20?= =?UTF-8?q?V3.3-BUG-FIX=20=20=20=20=20=20=2022271:=20ALF-3712:=20Merged=20?= =?UTF-8?q?HEAD=20to=20V3.3=20=20=20=20=20=20=20=20=20=2022249:=20Bin=20co?= =?UTF-8?q?ntents=20were=20not=20being=20packaged.=20=20=20=20=20=20=20222?= =?UTF-8?q?72:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=2022067:=20ALF-4479:=20when=20using=20webdav=20inline=20?= =?UTF-8?q?edit=20on=20webdav=20+=20MS=20Word=202003=20+IE6,=20one=20gets:?= =?UTF-8?q?=20Unable=20to=20check=20in=20Content=20Node=20due=20to=20syste?= =?UTF-8?q?m=20error.=20Access=20Denied.=20You=20do=20not=20have=20the=20a?= =?UTF-8?q?ppropriate=20permissions=20to=20perform=20this=20operation.=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20-=20Do=20not=20unlock=20a?= =?UTF-8?q?=20working=20copy.=20=20=20=20=20=20=2022273:=20Merged=20DEV/TE?= =?UTF-8?q?MPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=2021729:=20ALF-3?= =?UTF-8?q?112:=20Property=20parameterTemplates=20not=20resolved=20correct?= =?UTF-8?q?ly=20for=20SimpleTemplateActionDefinition=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20The=20temporary=20fix=20for=20unconfigurable?= =?UTF-8?q?=20valueSeparator=20property.=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20https://jira.springframework.org/browse/SPR-7429=20=20=20?= =?UTF-8?q?=20=20=20=2022274:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=2021993:=20ALF-4396:=20webdav=20"supporte?= =?UTF-8?q?dlock"=20propfind=20request=20returns=20malformed=20response=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20WebDAV=20supported=20lock?= =?UTF-8?q?=20elements=20were=20wrapped=20by=20=E2=80=9Clockentry=E2=80=9D?= =?UTF-8?q?=20elements=20according=20to=20the=20WebDAV=20specification.=20?= =?UTF-8?q?=20=20=20=20=20=2022276:=20ALF-3890:=20FTP=20Change=20Working?= =?UTF-8?q?=20Directory=20(CWD)=20command=20works=20with=20root-relative?= =?UTF-8?q?=20paths=20with=20more=20than=20one=20component=20=20=20=20=20?= =?UTF-8?q?=20=2022277:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2022076:=20ALF-3579:=20Open=20the=20Details=20P?= =?UTF-8?q?age=20URL=20removes=20the=20header,=20navigation=20bar=20etc=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20The=20identifiers=20for=20m?= =?UTF-8?q?odify=20action=20tag=20and=20details'=20actions=20tag=20should?= =?UTF-8?q?=20be=20different=20in=20the=20details=20pages.=20For=20documen?= =?UTF-8?q?ts:=20=20=20=20=20=20=20=20=20=20=20=20=20in=20the=20filelink-d?= =?UTF-8?q?etails.jsp=20and=20document-details.jsp.=20For=20spaces:=20in?= =?UTF-8?q?=20the=20space-details.jsp=20and=20spacelink-details.jsp.=20=20?= =?UTF-8?q?=20=20=20=20=2022285:=20Merged=20HEAD=20to=20V3.3=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2022284:=20Fix=20for=20ALF-3063=20"Incorrect=20?= =?UTF-8?q?behaviour=20on=20filtering=20by=20tag=20in=20Repository".=20Lab?= =?UTF-8?q?els=20updated=20to=20more=20accurately=20reflect=20behaviour.?= =?UTF-8?q?=20=20=20=20=20=20=2022299:=20Fix=20for=20ALF-3893:=20lucene.in?= =?UTF-8?q?dexer.mergerTargetIndexCount=20is=20redundant=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20-=20this=20property=20is=20now=20used=20to=20contro?= =?UTF-8?q?l=20the=20merging=20of=20indexes=20as=20was=20intended=20=20=20?= =?UTF-8?q?=20=20=20=2022309:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20(Appr?= =?UTF-8?q?oved=20by=20Roy)=20=20=20=20=20=20=20=20=20=2021035:=20ALF-2588?= =?UTF-8?q?:=20RM:=20Export=20and=20import=20of=20file=20plan=20causes=20d?= =?UTF-8?q?isposition=20errors=20=20=20=20=20=20=20=20=20=20=20=20=20When?= =?UTF-8?q?=20content=20is=20imported=20from=20acp=20the=20actionId=20that?= =?UTF-8?q?=20points=20to=20the=20action=20NodeRef=20is=20old=20in=20the?= =?UTF-8?q?=20imported=20content=20and=20NullPointerExcepption=20appears.?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20To=20avoid=20this=20we?= =?UTF-8?q?=20changed=20DispositionScheduleImpl.=20Now=20it=20stores=20the?= =?UTF-8?q?=20action=20that=20has=20different=20name=20and=20ID=20(when=20?= =?UTF-8?q?action=20is=20create=20it=20name=20equals=20id)=20in=20a=20sepa?= =?UTF-8?q?rate=20map.=20And=20when=20getDispositionActionDefinition(Strin?= =?UTF-8?q?g=20id)=20method=20is=20called=20it=20tries=20to=20retrieve=20t?= =?UTF-8?q?he=20action=20from=20this=20map,=20if=20it=20hasn=E2=80=99t=20b?= =?UTF-8?q?een=20found=20earlier.=20=20=20=20=20=20=2022325:=20Fix=20for?= =?UTF-8?q?=20ALF-4428:=20Incorrect=20behaviour=20of=20Consumer=20and=20Co?= =?UTF-8?q?ntributor=20permissions=20with=20Quickr=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20-=20unit=20test=20pass=20=20=20=20=20=20=2022334:=20Merge?= =?UTF-8?q?d=20HEAD=20to=20V3.3=20=20=20=20=20=20=20=20=20=2022331:=20Fixe?= =?UTF-8?q?s:=20ALF-3558:=20Input=20and=20variable=20encoding=20issues=20i?= =?UTF-8?q?n=20Share=20Calendar=20&=20API=20JSON=20data.=20=20=20=20=20=20?= =?UTF-8?q?=2022355:=20ALF-4489:=20Special=20Characters=20Create=20Stack?= =?UTF-8?q?=20Overflow=20Exception=20in=20the=20Group=20Admin=20Console=20?= =?UTF-8?q?for=20Share=20in=20Internet=20Explorer.=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20Fixed=20missing=20encoding=20and=20also=20added=20guard?= =?UTF-8?q?=20code=20to=20prevent=20stack=20overflow=20problem=20in=20case?= =?UTF-8?q?=20of=20future=20error.=20=20=20=20=20=20=2022356:=20Fix=20for?= =?UTF-8?q?=20ALF-4384=20-=20missing=20JSP=20page=20directive=20=20=20=20?= =?UTF-8?q?=20=20=2022360:=20Fix=20for=20ALF-4428:=20Incorrect=20behaviour?= =?UTF-8?q?=20of=20Consumer=20and=20Contributor=20permissions=20with=20Qui?= =?UTF-8?q?ckr=20=20=20=20=20=20=20=20=20=20-=20unit=20test=20pass=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20-=20no=20abstain=20allowed=20=20=20=20?= =?UTF-8?q?=20=20=2022365:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=2021874:=20ALF-2641:=20WebDav=20Permission?= =?UTF-8?q?=20Issues=20-=20MAC=20OSX=20Finder=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20The=20createExclusive=20field=20was=20introduced=20?= =?UTF-8?q?instead=20of=20m=5Fscope.=20New=20algorithm=20of=20lockscope=20?= =?UTF-8?q?determination=20was=20added.=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20Also=20ALF-4008=20compliant=20fix=20provided=20with=20thi?= =?UTF-8?q?s.=20=20=20=20=20=20=20=20=20=2021812:=20ALF-4008:=20save=20a?= =?UTF-8?q?=20MS=20Word=20change=20over=20webdav=20after=20a=202-3=20minut?= =?UTF-8?q?es=20delay=20causes=20the=20error=20'XXX.doc=20is=20currently?= =?UTF-8?q?=20in=20use.=20Please=20try=20again=20later.'=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20Modified=20LOCK=20method,=20it=20gets=20a?= =?UTF-8?q?=20scope=20from=20NodeRef=20property=20if=20m=5Fscope=20field?= =?UTF-8?q?=20is=20not=20defined.=20=20=20=20=20=20=2022367:=20Merged=20DE?= =?UTF-8?q?V/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=2021442:=20A?= =?UTF-8?q?LF-2587:=20WEBDAV=20error=20in=20Windows=207=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20-=20variant=20generateLockDiscoveryXML=20m?= =?UTF-8?q?ethods=20were=20factored=20into=20a=20single=20one=20capable=20?= =?UTF-8?q?of=20generating=20a=20namespaced=20LOCK=20response=20compatible?= =?UTF-8?q?=20with=20Windows=207=20when=20its=20user=20agent=20header=20is?= =?UTF-8?q?=20detected.=20=20=20=20=20=20=2022368:=20Merged=20DEV/TEMPORAR?= =?UTF-8?q?Y=20to=20V3.3=20=20=20=20=20=20=20=20=20=2020919:=20ALF-2834:?= =?UTF-8?q?=20All=20day=20events=20created=20in=20Outlook=20not=20appearin?= =?UTF-8?q?g=20in=20Meeting=20Workspace=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20Different=20date=20format=20is=20used=20by=20Outlook=20wh?= =?UTF-8?q?en=20creating=20all=20day=20meeting=20request=20and=20meeting?= =?UTF-8?q?=20request=20specifying=20date=20and=20time.=20The=20code=20was?= =?UTF-8?q?=20changed=20to=20handle=20both=20situations=20accordingly.=20?= =?UTF-8?q?=20=20=20=20=20=2022369:=20Merged=20DEV/TEMPORARY=20to=20V3.3?= =?UTF-8?q?=20(With=20simplifications)=20=20=20=20=20=20=20=20=20=2021470:?= =?UTF-8?q?=20ALF-3796:=20Locale=20is=20not=20always=20set/reset=20on=20ev?= =?UTF-8?q?ery=20request=20thread=20=20=20=20=20=20=20=20=20=20=20=20=20-?= =?UTF-8?q?=20A=20GlobalLocalizationFilter=20sits=20in=20front=20of=20ALL?= =?UTF-8?q?=20requests=20and=20sets=20a=20default=20fallback=20locale=20on?= =?UTF-8?q?=20I18NUtil=20=20=20=20=20=20=20=20=20=20=20=20=20-=20Moved=20B?= =?UTF-8?q?aseServlet.setLanguageFromRequestHeader=20into=20this=20filter?= =?UTF-8?q?=20and=20made=20sure=20it=20always=20falls=20back=20to=20a=20de?= =?UTF-8?q?fault=20locale=20=20=20=20=20=20=20=20=20=20=20=20=20-=20Subseq?= =?UTF-8?q?uent=20filters=20/=20servlets=20in=20faces=20chain=20may=20over?= =?UTF-8?q?ride=20this=20with=20user=20preferred=20locale=20after=20authen?= =?UTF-8?q?tication=20=20=20=20=20=20=2022370:=20ALF-3868:=20Fix=20for=20c?= =?UTF-8?q?ompatibility=20with=20Sun=20Directory=20Server=20=20=20=20=20?= =?UTF-8?q?=20=2022371:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2021811:=20ALF-4067:=20Display=20Value=20for=20?= =?UTF-8?q?Action=20Constraint=20breaking=20a=20java=20eval=20in=20Share?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20When=20a=20node=20doesn'?= =?UTF-8?q?t=20have=20a=20ContentModel.PROP=5FTITLE=20property=20it=20is?= =?UTF-8?q?=20added=20to=20AllowableValues=20with=20PROP=5FNAME=20value.?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=2021795:=20ALF-4067:=20Display=20Va?= =?UTF-8?q?lue=20for=20Action=20Constraint=20breaking=20a=20java=20eval=20?= =?UTF-8?q?in=20Share=20=20=20=20=20=20=20=20=20=20=20=20=20The=20fix=20in?= =?UTF-8?q?troduces=20the=20code=20which=20doesn't=20add=20a=20node=20to?= =?UTF-8?q?=20AllowableValues=20if=20it=20doesn't=20have=20a=20ContentMode?= =?UTF-8?q?l.PROP=5FTITLE=20property.=20=20=20=20=20=20=2022378:=20ALF-379?= =?UTF-8?q?6:=20Fixed=20compilation=20error=20-=20BaseServlet.setLanguageF?= =?UTF-8?q?romRequestHeader=20replaced=20by=20global=20filter=20=20=20=20?= =?UTF-8?q?=20=20=2022380:=20ALF-3761:=20War=20bundles=20+=20extension=20s?= =?UTF-8?q?amples=20now=20include=20alfresco-global.properties=20in=20corr?= =?UTF-8?q?ect=20position=20in=20hierarchy=20=20=20=20=20=20=2022386:=20AL?= =?UTF-8?q?F-3887:=20Two=20versions=20of=20geronimo-activation=20are=20shi?= =?UTF-8?q?pped=20=20=20=20=20=20=20=20=20=20-=20Removed=20the=20older=20v?= =?UTF-8?q?ersion=20=20=20=20=20=20=2022402:=20WCM=20-=20add=20more=20debu?= =?UTF-8?q?g=20logging=20only=20=20=20=20=20=20=2022405:=20Change=20notifi?= =?UTF-8?q?cation=20handler=20not=20enabled=20by=20the=20server=20configur?= =?UTF-8?q?ation=20bean.=20ALF-4715.=20=20=20=20=20=20=2022407:=20Merged?= =?UTF-8?q?=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=2022231?= =?UTF-8?q?:=20ALF-4096:=20Share=20point=20module=20is=20causing=20file=20?= =?UTF-8?q?descriptor=20leaks.=20=20=20=20=20=20=20=20=20=20=20=20=20The?= =?UTF-8?q?=20following=20changes=20were=20added=20to=20VtiIfHeaderAction?= =?UTF-8?q?=20and=20GetDocumentMethod:=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20-=20code=20that=20copies=20data=20between=20streams=20was=20?= =?UTF-8?q?replaced=20by=20org.apache.commons.io.IOUtils.copy()=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20-=20correct=20stream=20closing=20?= =?UTF-8?q?was=20added=20for=20all=20cases=20including=20exceptions=20whil?= =?UTF-8?q?e=20copying=20=20=20=20=20=20=2022411:=20Merged=20DEV/TEMPORARY?= =?UTF-8?q?=20to=20V3.3=20=20=20=20=20=20=20=20=20=2021864:=20ALF-4371:=20?= =?UTF-8?q?Error=20occurs=20if=20user=20try=20to=20find=20event=20from=20m?= =?UTF-8?q?eeting=20place=20=20=20=20=20=20=20=20=20=20=20=20=20Replaced?= =?UTF-8?q?=20incorrect=20NamespaceService.CONTENT=5FMODEL=5FPREFIX=20with?= =?UTF-8?q?=20NamespaceService.CONTENT=5FMODEL=5F1=5F0=5FURI=20in=20QName?= =?UTF-8?q?=20creation.=20=20=20=20=20=20=2022412:=20Merged=20DEV/TEMPORAR?= =?UTF-8?q?Y=20to=20V3.3=20=20=20=20=20=20=20=20=20=2022018:=20ALF-4403:?= =?UTF-8?q?=20Search=20on=20users=20in=20JSF=20client=20and=20SHARE=20do?= =?UTF-8?q?=20not=20specify=20"cm:person"=20type=20clause=20in=20the=20que?= =?UTF-8?q?ry=20leading=20to=20incorrect=20results=20in=20user=20searching?= =?UTF-8?q?.=20=20=20=20=20=20=20=20=20=20=20=20=20People=20searches=20in?= =?UTF-8?q?=20Alfresco=20and=20share=20are=20restricted=20by=20=E2=80=9Ccm?= =?UTF-8?q?:person=E2=80=9D=20type.=20=20=20=20=20=20=20=20=20=2021988:=20?= =?UTF-8?q?ALF-4403:=20Search=20on=20users=20in=20JSF=20client=20and=20SHA?= =?UTF-8?q?RE=20do=20not=20specify=20"cm:person"=20type=20clause=20in=20th?= =?UTF-8?q?e=20query=20leading=20to=20incorrect=20results=20in=20user=20se?= =?UTF-8?q?arching.=20=20=20=20=20=20=20=20=20=20=20=20=20People=20searche?= =?UTF-8?q?s=20in=20Alfresco=20and=20share=20are=20restricted=20by=20?= =?UTF-8?q?=E2=80=9Ccm:person=E2=80=9D=20type.=20=20=20=20=20=20=2022418:?= =?UTF-8?q?=20ALF-4578:=20Avoid=20ConcurrentModificationException=20in=20A?= =?UTF-8?q?VMDeploymentTarget=20=20=20=20=20=20=2022420:=20Fixed=20ALF-958?= =?UTF-8?q?:=20Target=20associations=20aren't=20copied=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20-=20Added=20CopyBehaviourCallback.=20getAssociation?= =?UTF-8?q?CopyAction=20=20=20=20=20=20=20=20=20=20-=20Default=20behaviour?= =?UTF-8?q?:=20=20=20=20=20=20=20=20=20=20=20=20-=20Remove=20existing=20as?= =?UTF-8?q?sociations=20of=20same=20type=20when=20copying=20OVER=20an=20ex?= =?UTF-8?q?isting=20node=20(e.g.=20check-in)=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20-=20Copy=20the=20association=20using=20a=20new=20target?= =?UTF-8?q?=20if=20the=20target=20is=20copied=20in=20the=20same=20call=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20-=20Copy=20the=20association?= =?UTF-8?q?=20to=20the=20original=20target=20if=20the=20target=20is=20not?= =?UTF-8?q?=20copied=20in=20the=20same=20call=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20-=20Abstract=20behaviour=20(for=20those=20that=20have=20impl?= =?UTF-8?q?emented=20a=20CopyBehaviourCallback):=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20-=20Remove=20existing=20associations=20of=20same=20?= =?UTF-8?q?type=20when=20copying=20OVER=20an=20existing=20node=20(e.g.=20c?= =?UTF-8?q?heck-in)=20=20=20=20=20=20=20=20=20=20=20=20-=20Only=20copy=20t?= =?UTF-8?q?he=20association=20to=20a=20new=20target=20if=20the=20original?= =?UTF-8?q?=20target=20is=20copied=20=20=20=20=20=20=2022421:=20ALF-4641:?= =?UTF-8?q?=20Strip=20ticket=20parameter=20on=20login=20page=20redirect=20?= =?UTF-8?q?to=20avoid=20endless=20redirect=20loop=20=20=20=20=20=20=202242?= =?UTF-8?q?2:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=2021201:=20ALF-1804:=20Passthru=20server=20check=20gets=20c?= =?UTF-8?q?onfused=20when=20a=20server=20goes=20offline=20=20=20=20=20=20?= =?UTF-8?q?=2022423:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=2021891:=20ALF-3356:=20Error=20changing=20own=20us?= =?UTF-8?q?er=20role=20from=20coordinator=20to=20consumer=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20When=20a=20user=20changes=20the=20Roles?= =?UTF-8?q?,=20all=20Permissions=20are=20immediately=20deleted=20and=20new?= =?UTF-8?q?=20selected=20permissions=20are=20created.=20If=20all=20permiss?= =?UTF-8?q?ions=20are=20deleted=20then=20the=20user=20doesn't=20have=20acc?= =?UTF-8?q?ess=20for=20permissions=20creation.=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20If=20the=20user=20currently=20has=20permission=20ch?= =?UTF-8?q?ange=20permission=20the=20currently=20set=20of=20permissions=20?= =?UTF-8?q?is=20cleared=20and=20new=20permissions=20are=20added=20from=20a?= =?UTF-8?q?=20System=20User=20authority.=20=20=20=20=20=20=2022424:=20Merg?= =?UTF-8?q?ed=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=20211?= =?UTF-8?q?82:=20ALF-1786:=20Remote=20Opensearch=20request=20mimetype=20mi?= =?UTF-8?q?ssing=20=20=20=20=20=20=20=20=20=20=20=20=20SearchProxy=20was?= =?UTF-8?q?=20changed=20to=20provide=20original=20User-Agent=20header.=20H?= =?UTF-8?q?TTPProxy=20was=20extended=20to=20set=20request=20headers.=20New?= =?UTF-8?q?=20overridable=20method=20setRequestHeaders=20was=20added=20to?= =?UTF-8?q?=20provide=20ability=20of=20setting=20headers.=20=20=20=20=20?= =?UTF-8?q?=20=2022425:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=2022165:=20ALF-197:=20When=20returning=20to=20t?= =?UTF-8?q?he=20first=20step=20of=20Advanced=20Workflow=20creation=20from?= =?UTF-8?q?=20second=20or=20third=20steps=20it's=20always=20Adhoc=20Task?= =?UTF-8?q?=20chosen=20there=20=20=20=20=20=20=20=20=20=20=20=20=20The=20s?= =?UTF-8?q?electedWorkflow=20variable=20was=20reseting=20every=20time=20on?= =?UTF-8?q?=20"Choose=20Workflow"=20step=20=20=20=20=20=20=2022426:Merged?= =?UTF-8?q?=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=2021323?= =?UTF-8?q?:=20ALF-687:=20Error=20when=20invoking=20webservices=20via=20SS?= =?UTF-8?q?L=20repository=20location=20url.=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20Add=20a=20new=20overload=20of=20ContentUtils.putConten?= =?UTF-8?q?t()=20method=20with=20the=20isSSL=20argument=20at=20the=20end.?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20If=20this=20parameter=20?= =?UTF-8?q?value=20is=20true=20then=20SSLSocket=20is=20used=20and=20Socket?= =?UTF-8?q?=20otherwise.=20=20=20=20=20=20=2022428:=20ALF-3490:=20Unfriend?= =?UTF-8?q?ly=20error=20messages=20from=20WebDAV=20when=20content=20doesn'?= =?UTF-8?q?t=20exist=20=20=20=20=20=20=20=20=20=20-=20Generalized=20ALF-42?= =?UTF-8?q?07=20solution=20so=20that=20the=20error=20page=20instead=20disp?= =?UTF-8?q?lays=20a=20status=20404=20message=20=20=20=20=20=20=2022429:=20?= =?UTF-8?q?Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=2021325:=20ALF-3502:=20Logging=20in=20FacesHelper.getManagedBe?= =?UTF-8?q?an=20on=20failure=20to=20create=20bean=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20Detailed=20logging=20of=20the=20EvaluationExcept?= =?UTF-8?q?ion=20for=20ValueBinding=20was=20added.=20=20=20=20=20=20=20224?= =?UTF-8?q?30:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=2020974:=20ALF-2695:=20mimetypes-extension-context.xml.s?= =?UTF-8?q?ample=20does=20not=20use=20the=20correct=20classes=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20Changed=20the=20type=20of=20the=20be?= =?UTF-8?q?an=20id=3D"mimetypeConfigService"=20from=20=E2=80=9C"org.alfres?= =?UTF-8?q?co.config.xml.XMLConfigService=E2=80=9D=20to=20=20=E2=80=9Corg.?= =?UTF-8?q?springframework.extensions.config.xml.XMLConfigService=E2=80=9D?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20Renamed=20mimetypes-exte?= =?UTF-8?q?nsion-context.xml.sample=20file=20=20to=20file=20=20mimetypes-e?= =?UTF-8?q?xtension.xml.sample.=20=20The=20file=20mimetypes-extension-cont?= =?UTF-8?q?ext.xml.sample=20was=20interpreted=20like=20spring=20context=20?= =?UTF-8?q?file.=20It=20wasn=E2=80=99t=20correct.=20=20=20=20=20=20=202243?= =?UTF-8?q?1:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=2021099:=20ALF-3046:=20UI=20-=20Import=20feature=20not=20av?= =?UTF-8?q?ailable=20to=20contributor=20user=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20The=20fix=20also=20covers=20related=20bug=20ALF-2802.?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20Permission=20=E2=80=98Wr?= =?UTF-8?q?ite=E2=80=99=20was=20replaced=20by=20=E2=80=98CreateChildren?= =?UTF-8?q?=E2=80=99=20for=20import=20action=20because=20contributor=20has?= =?UTF-8?q?=20=E2=80=98AddChildren=E2=80=99=20(not=20=E2=80=98Write?= =?UTF-8?q?=E2=80=99)=20permission.=20=20=20=20=20=20=2022432:=20Merged=20?= =?UTF-8?q?DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=2020973:?= =?UTF-8?q?=20ALF-3244:=20alfresco-sample-website.war=20does=20not=20deplo?= =?UTF-8?q?y=20to=20bundled=20Tomcat=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20The=20cause=20of=20the=20corrupted=20alfresco-sample-website?= =?UTF-8?q?.war=20deployment=20is=20the=20usage=20of=20the=20SSIFilter=20i?= =?UTF-8?q?n=20the=20application.=20=20=20=20=20=20=20=20=20=20=20=20=20On?= =?UTF-8?q?ly=20Contexts=20which=20are=20marked=20as=20privileged=20may=20?= =?UTF-8?q?use=20SSI=20features.=20For=20this=20reason,=20the=20context=20?= =?UTF-8?q?has=20been=20marked=20as=20privileged=20in=20META-INF/context.x?= =?UTF-8?q?ml=20=20=20=20=20=20=2022433:=20Merged=20DEV/TEMPORARY=20to=20V?= =?UTF-8?q?3.3=20=20=20=20=20=20=20=20=20=2021190:=20ALF-3751:=20Unintenti?= =?UTF-8?q?onal=20copy/remove=20of=20'Web=20Forms'=20space=20removes=20for?= =?UTF-8?q?m=20associations=20in=20Web=20Projects=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20Parent=20validation=20before=20deleting=20was=20?= =?UTF-8?q?added.=20Now=20deleted=20web=20form=20is=20removed=20from=20Web?= =?UTF-8?q?=20Project=20only=20if=20this=20form=20is=20located=20in=20orig?= =?UTF-8?q?inal=20Web=20Form=20folder.=20=20=20=20=20=20=2022434:=20Merged?= =?UTF-8?q?=20DEV/TEMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=2021490?= =?UTF-8?q?:=20ALF-4099:=20Customer=20concern=20about=20String=20compariso?= =?UTF-8?q?n=20operators=20=3D=3D=20vs=20equals=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20Comparison=20operator=20was=20replaced=20by=20equal?= =?UTF-8?q?s/EqualsHelper.nullSafeEquals=20in=20the=20ContentFilterLanguag?= =?UTF-8?q?esMap=20DocumentNavigator=20UIAjaxTagPicker=20Presence=20classe?= =?UTF-8?q?s.=20=20=20=20=20=20=20=20=20=20=20=20=20DocumentNavigator.getA?= =?UTF-8?q?ttributeName()=20method=20was=20changed=20because=20the=20previ?= =?UTF-8?q?ous=20method's=20logic=20always=20returned=20escapedLocalName?= =?UTF-8?q?=20in=20any=20case.=20=20=20=20=20=20=2022436:=20Merged=20DEV/T?= =?UTF-8?q?EMPORARY=20to=20V3.3=20=20=20=20=20=20=20=20=20=2022063:=20ALF-?= =?UTF-8?q?4494=20:=20Share=20show=20error=20if=20versionable=20document?= =?UTF-8?q?=20has=20no=20version=20history.=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=201.=20evaluator.lib.js=20was=20modified=20to=20prevent?= =?UTF-8?q?=20NPE=20if=20no=20version=20history=20exists=20for=20document.?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=202.=20Result=20was=20manu?= =?UTF-8?q?ally=20tested.=20=20=20=20=20=20=2022437:=20ALF-2796:=20java.na?= =?UTF-8?q?ming.referral=20is=20set=20to=20"follow"=20in=20the=20LDAP=20co?= =?UTF-8?q?ntexts=20to=20avoid=20PartialResultExceptions=20on=20LDAP=20syn?= =?UTF-8?q?c=20=20=20=20=20=20=2022466:=20Merge=20from=20V3.2=20to=20V3.3.?= =?UTF-8?q?=20Fix=20for=20ALF-4741.=20=20=20=20=20=20=20=20=20=20V3.2:=202?= =?UTF-8?q?2465=20Fix=20for=20ALF-4741.=20Repository=20Web=20Scripts=20can?= =?UTF-8?q?=20produce=20a=20corrupted=20response=20after=20a=20transaction?= =?UTF-8?q?=20collision/retry.=20=20=20=20=20=20=2022469:=20Fix=20for=20CI?= =?UTF-8?q?FS=20long=20directory=20path=20results=20in=20duplicate=20folde?= =?UTF-8?q?r=20displays.=20ALF-3938.=20=20=20=20=20=20=20=20=20=20Removed?= =?UTF-8?q?=20(hopefully)=20last=20of=20the=20hardcoded=20buffer=20length?= =?UTF-8?q?=20limits.=20=20=20=20=20=20=2022472:=20Fixed=20ALF-4670:=20XAM?= =?UTF-8?q?=20retainUntil=20value=20does=20not=20propagate=20down=20the=20?= =?UTF-8?q?space=20hierarchy=20=20=20=20=20=20=2022473:=20Fixed=20ALF-4656?= =?UTF-8?q?:=20Deleted=20Content=20Backup=20should=20ignore=20unrecognised?= =?UTF-8?q?=20URLs=20=20=20=20=20=20=20=20=20=20-=20Also=20fixes=20ALF-465?= =?UTF-8?q?7:=20Content=20stored=20on=20XAM=20is=20not=20cleaned=20up=20co?= =?UTF-8?q?rrectly=20=20=20=20=20=20=20=20=20=20-=20Errors=20in=20the=20li?= =?UTF-8?q?steners=20are=20logged=20only=20=20=20=20=20=20=20=20=20=20-=20?= =?UTF-8?q?ContentStoreCleanerListener=20checks=20and=20warns=20if=20the?= =?UTF-8?q?=20URL=20is=20unsupported=20=20=20=20=20=20=2022474:=20Fix=20to?= =?UTF-8?q?=20web.xml=20to=20correctly=20validate=20and=20therefore=20depl?= =?UTF-8?q?oy=20on=20JBoss5.1.0=20=20=20=20=20=20=2022485:=20Fix=20for=20N?= =?UTF-8?q?FS=20losing=20contents=20during=20edit=20or=20copy.=20ALF-4737.?= =?UTF-8?q?=20=20=20=20=20=20=2022492:=20ALF-4652=20XAM=20bug=20fixes=20an?= =?UTF-8?q?d=20improvements:=20Respect=200=20'retentionPeriodDays'=20=20?= =?UTF-8?q?=20=20=20=20=2022501:=20Fixed=20ALF-4763=20XAM-enabled=20nodes?= =?UTF-8?q?=20must=20not=20go=20to=20the=20archive://SpacesStore=20=20=20?= =?UTF-8?q?=20=20=20=2022504:=20Fix=20for=20MS=20Word=20mimetype=20is=20ch?= =?UTF-8?q?anged=20when=20editing=20via=20CIFS.=20ALF-3772.=20=20=20=20=20?= =?UTF-8?q?=20=2022520:=20ALF-4768:=20WCM=20(w/=20virt=20svr)=20-=20submit?= =?UTF-8?q?=20=20(no=20need=20to=20virtualize=20direct=20submit=20workflow?= =?UTF-8?q?s)=20=20=20=20=20=20=2022526:=20Externalised=20setting=20of=20B?= =?UTF-8?q?INARIES,=20plus=20added=20bin=20with=20jars=20and=20dlls=20=20?= =?UTF-8?q?=20=20=20=20=2022561:=20ALF-4792:=20WCM=20virt=20svr=20-=20add?= =?UTF-8?q?=20experimental=20option=20for=20lazy=20deployment=20(defer=20s?= =?UTF-8?q?tartup=20of=20dependent=20webapps=20until=20accessed)=20=20=20?= =?UTF-8?q?=20=20=20=2022611:=20Fixed=20ALF-1893:=20Windows=207=20SSP=20Re?= =?UTF-8?q?ad-only.=20=20=20=20=20=20=20=20=20=20Note:=20Relies=20on=20the?= =?UTF-8?q?=20patched=20Excel=20and=20PowerPoint=20mimetypes,=20but=20also?= =?UTF-8?q?=20falls=20back=20to=20file=20exension.=20=20=20=20=20=20=20226?= =?UTF-8?q?12:=20Merged=20HEAD=20to=20BRANCHES/V3.3:=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=2022609:=20Resolve=20ALF4822,=20ALF4818=20=20=20=20=20?= =?UTF-8?q?=20=2022628:=20ALF-3239:=20Added=20encoding=20elements=20to=20m?= =?UTF-8?q?ysql=20db=20url=20=20=20=20=20=20=2022656:=20Fix=20for=20Solari?= =?UTF-8?q?s/Gedit=20problem,=20keep=20a=20mapping=20for=20the=20original?= =?UTF-8?q?=20file=20handle=20to=20the=20new=20path=20after=20a=20rename.?= =?UTF-8?q?=20ALF-4843.=20=20=20=20=20=20=2022673:=20ALF-4845:=20Person=20?= =?UTF-8?q?and=20Group=20member=20deletion=20performance=20fix=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20-=20Don't=20batch=20load=20all=20a=20group's?= =?UTF-8?q?=20members=20when=20trying=20to=20delete=20one=20of=20them!=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20-=20Can=20result=20in=20infeasibly?= =?UTF-8?q?=20large=20hibernate=20sessions=20when=20trying=20to=20delete?= =?UTF-8?q?=20a=20person=20/=20LDAP=20sync=20in=20a=20repository=20with=20?= =?UTF-8?q?very=20large=20groups=20=20=20=20=20=20=20=20=20=20-=20Switched?= =?UTF-8?q?=20off=20batch=20loading=20in=20NodeService.removeChild()=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20-=20Avoided=20unnecessary=20use=20of=20?= =?UTF-8?q?removeAuthority=20in=20PersonService.deletePerson()=20=20=20=20?= =?UTF-8?q?=20=20=2022674:=20Merged=20DEV/TEMPORARY=20to=20V3.3=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=2022653:=20ALF-661:=20There=20is=20no=20way?= =?UTF-8?q?=20to=20determine=20the=20protocol,=20hostname=20and=20port=20f?= =?UTF-8?q?rom=20a=20javascript=20kicked=20off=20by=20JBPM=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20These=20variables=20are=20now=20availab?= =?UTF-8?q?le=20for=20use=20in=20workflow=20and=20action=20javascript=20an?= =?UTF-8?q?d=20they=20are=20wired=20to=20the=20corresponding=20parameters?= =?UTF-8?q?=20that=20already=20exist=20in=20the=20sysAdmin=20subsystem.=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20urls.alfresco.prot?= =?UTF-8?q?ocol=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20urls.alfres?= =?UTF-8?q?co.host=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20urls.alf?= =?UTF-8?q?resco.port=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20urls.?= =?UTF-8?q?alfresco.context=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20urls.share.protocol=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20urls.share.host=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20urls.share.port=20=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20urls.share.context=20=20=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20See=20bug=20for=20example=20usage=20=20=20=20=20=20=2022676:?= =?UTF-8?q?=20Merged=20HEAD=20to=20V3.3:=20=20=20=20=20=20=20=20=20=202030?= =?UTF-8?q?6:=20Google=20Doc=20integration=20fixes:=20=20=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20-=20Fixed=20up=20inconsistancies=20in=20powerpoint?= =?UTF-8?q?=20and=20excel=20mimetypes=20set=20throughout=20the=20code=20?= =?UTF-8?q?=20=20=20=20=20=20=20=20=20=20-=20Unit=20tests=20failures=20for?= =?UTF-8?q?=20excel=20sheets=20fixed=20=20=20=20=20=20=20=20=20=20=20-=20A?= =?UTF-8?q?ble=20to=20now=20create=20and=20checkout=20docs,=20sheets=20and?= =?UTF-8?q?=20presentations=20successfullly=20=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=20-=20Docs,=20sheets=20and=20presentations=20downloadable=20an?= =?UTF-8?q?d=20viewable=20=20=20=20=20=20=20=20=20=20=20-=20Fixed=20ALF-27?= =?UTF-8?q?00=20=20=20=20=20=20=20=20=20=20(See=20ALF-4827)=20=20=20=20=20?= =?UTF-8?q?=20=2022715:=20Merge=20from=20V3.2=20to=20V3.3.=20=20=20=20=20?= =?UTF-8?q?=20=20=20=20=20r.=2022713.=20Fix=20for=20ALF-4946=20Possible=20?= =?UTF-8?q?NullPointerException=20during=20creation=20of=20thumbnails=20wh?= =?UTF-8?q?ose=20names=20are=20null-valued.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@22725 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../repository/groups/authority.lib.ftl | 4 +- .../documentlibrary/evaluator.lib.js | 2 +- .../repo/web/scripts/bean/SearchProxy.java | 27 +- .../org/alfresco/repo/webdav/LockMethod.java | 915 ++++++++---------- .../alfresco/repo/webdav/PropFindMethod.java | 36 +- .../alfresco/repo/webdav/PropPatchMethod.java | 3 +- .../alfresco/repo/webdav/UnlockMethod.java | 8 +- .../java/org/alfresco/repo/webdav/WebDAV.java | 7 + .../alfresco/repo/webdav/WebDAVMethod.java | 72 +- .../alfresco/web/app/servlet/HTTPProxy.java | 10 + 10 files changed, 551 insertions(+), 533 deletions(-) diff --git a/config/alfresco/templates/webscripts/org/alfresco/repository/groups/authority.lib.ftl b/config/alfresco/templates/webscripts/org/alfresco/repository/groups/authority.lib.ftl index 139340ce37..94437b2e66 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/repository/groups/authority.lib.ftl +++ b/config/alfresco/templates/webscripts/org/alfresco/repository/groups/authority.lib.ftl @@ -11,10 +11,10 @@ <#if authority.adminGroup??>"isAdminGroup": ${authority.adminGroup?string("true", "false")}, <#-- end of group specific properties --> <#if authority.authorityType = "GROUP"> - "url": "/api/groups/${authority.shortName}" + "url": "/api/groups/${authority.shortName?url}" <#if authority.authorityType = "USER"> - "url": "/api/people/${authority.shortName}" + "url": "/api/people/${authority.shortName?url}" } diff --git a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js index a59557de53..004ecb2f54 100644 --- a/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js +++ b/config/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/evaluator.lib.js @@ -169,7 +169,7 @@ var Evaluator = var wcNode = node.properties["source"]; custom["isWorkingCopy"] = true; custom["workingCopyOriginal"] = wcNode.nodeRef; - if (wcNode.hasAspect("cm:versionable") && wcNode.versionHistory.length > 0) + if (wcNode.hasAspect("cm:versionable") && wcNode.versionHistory !== null && wcNode.versionHistory.length > 0) { custom["workingCopyVersion"] = wcNode.versionHistory[0].label; } diff --git a/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java b/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java index 37b99af19a..0483f72a37 100644 --- a/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java +++ b/source/java/org/alfresco/repo/web/scripts/bean/SearchProxy.java @@ -22,6 +22,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; +import java.net.URLConnection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -44,6 +46,7 @@ import org.dom4j.XPath; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; +import org.springframework.beans.factory.InitializingBean; import org.springframework.extensions.config.Config; import org.springframework.extensions.config.ConfigService; import org.springframework.extensions.webscripts.AbstractWebScript; @@ -52,7 +55,6 @@ import org.springframework.extensions.webscripts.WebScriptException; import org.springframework.extensions.webscripts.WebScriptRequest; import org.springframework.extensions.webscripts.WebScriptResponse; import org.springframework.extensions.webscripts.servlet.WebScriptServletRuntime; -import org.springframework.beans.factory.InitializingBean; /** @@ -166,7 +168,8 @@ public class SearchProxy extends AbstractWebScript implements InitializingBean } HttpServletResponse servletRes = WebScriptServletRuntime.getHttpServletResponse(res); - SearchEngineHttpProxy proxy = new SearchEngineHttpProxy(req.getServicePath() + "/" + req.getContextPath(), engine, engineUrl, servletRes); + SearchEngineHttpProxy proxy = new SearchEngineHttpProxy(req.getServicePath() + "/" + req.getContextPath(), + engine, engineUrl, servletRes, Collections.singletonMap("User-Agent", req.getHeader("User-Agent"))); proxy.service(); } @@ -184,20 +187,38 @@ public class SearchProxy extends AbstractWebScript implements InitializingBean private final static String ATOM_LINK_XPATH = "atom:link[@rel=\"first\" or @rel=\"last\" or @rel=\"next\" or @rel=\"previous\" or @rel=\"self\" or @rel=\"alternate\"]"; private String engine; private String rootPath; + private Map headers; /** * Construct * * @param requestUrl * @param response + * @param headers request headers * @throws MalformedURLException */ - public SearchEngineHttpProxy(String rootPath, String engine, String engineUrl, HttpServletResponse response) + public SearchEngineHttpProxy(String rootPath, String engine, String engineUrl, HttpServletResponse response, Map headers) throws MalformedURLException { super(engineUrl.startsWith("/") ? rootPath + engineUrl : engineUrl, response); this.engine = engine; this.rootPath = rootPath; + this.headers = headers; + } + + /* (non-Javadoc) + * @see org.alfresco.web.app.servlet.HTTPProxy#setRequestHeaders(java.net.URLConnection) + */ + @Override + protected void setRequestHeaders(URLConnection urlConnection) + { + if (headers != null) + { + for (Map.Entry entry: headers.entrySet()) + { + urlConnection.setRequestProperty(entry.getKey(), entry.getValue()); + } + } } /* (non-Javadoc) diff --git a/source/java/org/alfresco/repo/webdav/LockMethod.java b/source/java/org/alfresco/repo/webdav/LockMethod.java index d5b0840369..6b2be06678 100644 --- a/source/java/org/alfresco/repo/webdav/LockMethod.java +++ b/source/java/org/alfresco/repo/webdav/LockMethod.java @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2005-2010 Alfresco Software Limited. * * This file is part of Alfresco @@ -14,492 +14,427 @@ * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License - * along with Alfresco. If not, see . - */ -package org.alfresco.repo.webdav; - -import java.util.Date; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.http.HttpServletResponse; - -import org.alfresco.model.ContentModel; -import org.alfresco.model.WebDAVModel; -import org.alfresco.service.cmr.lock.LockService; -import org.alfresco.service.cmr.lock.LockType; -import org.alfresco.service.cmr.model.FileFolderService; -import org.alfresco.service.cmr.model.FileFolderUtil; -import org.alfresco.service.cmr.model.FileInfo; -import org.alfresco.service.cmr.model.FileNotFoundException; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.dom4j.DocumentHelper; -import org.dom4j.io.XMLWriter; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.xml.sax.Attributes; - -/** - * Implements the WebDAV LOCK method - * - * @author gavinc - */ -public class LockMethod extends WebDAVMethod -{ - public static final String EMPTY_NS = ""; - - protected int m_timeoutDuration = WebDAV.TIMEOUT_INFINITY; - - protected LockInfo lockInfo = new LockInfo(); - - protected String m_scope = null; - - protected String lockToken= null; - - /** - * Default constructor - */ - public LockMethod() - { - } - - /** - * Returns true if request has lock token in the If header - * - * @return boolean - */ - protected final boolean hasLockToken() - { - if (m_conditions != null) - { - for (Condition condition : m_conditions) - { - if (!condition.getLockTokensMatch().isEmpty()) - { - return true; - } - } - } - return false; - } - - /** - * Return the lock timeout, in minutes - * - * @return int - */ - protected final int getLockTimeout() - { - return m_timeoutDuration; - } - - /** - * Parse the request headers - * - * @exception WebDAVServerException - */ - protected void parseRequestHeaders() throws WebDAVServerException - { - // Get the depth - - parseDepthHeader(); - - // According to the specification: "Values other than 0 or infinity MUST NOT be used with the Depth header on a LOCK method.". - // The specification does not specify the error code for this case - so we use HttpServletResponse.SC_INTERNAL_SERVER_ERROR. - if (m_depth != WebDAV.DEPTH_0 && m_depth != WebDAV.DEPTH_INFINITY) - { - throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - - // Parse Lock tokens and ETags, if any - - parseIfHeader(); - - // Get the lock timeout value - - String strTimeout = m_request.getHeader(WebDAV.HEADER_TIMEOUT); - - // If the timeout header starts with anything other than Second - // leave the timeout as the default - - if (strTimeout != null && strTimeout.startsWith(WebDAV.SECOND)) - { - try - { - // Some clients send header as Second-180 Seconds so we need to - // look for the space - - int idx = strTimeout.indexOf(" "); - - if (idx != -1) - { - // Get the bit after Second- and before the space - - strTimeout = strTimeout.substring(WebDAV.SECOND.length(), idx); - } - else - { - // The string must be in the correct format - - strTimeout = strTimeout.substring(WebDAV.SECOND.length()); - } - m_timeoutDuration = Integer.parseInt(strTimeout); - } - catch (Exception e) - { - // Warn about the parse failure and leave the timeout as the - // default - - logger.warn("Failed to parse Timeout header: " + strTimeout); - } - } - - // DEBUG - - if (logger.isDebugEnabled()) - logger.debug("Timeout=" + getLockTimeout() + ", depth=" + getDepth()); - } - - /** - * Parse the request body - * - * @exception WebDAVServerException - */ - protected void parseRequestBody() throws WebDAVServerException - { - if (m_request.getContentLength() == -1) - { - return; - } - - Document body = getRequestBodyAsDocument(); - if (body != null) - { - Element rootElement = body.getDocumentElement(); - NodeList childList = rootElement.getChildNodes(); - - for (int i = 0; i < childList.getLength(); i++) - { - Node currentNode = childList.item(i); - switch (currentNode.getNodeType()) - { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - if (currentNode.getNodeName().endsWith(WebDAV.XML_LOCK_SCOPE)) - { - NodeList propertiesList = currentNode.getChildNodes(); - - for (int j = 0; j < propertiesList.getLength(); j++) - { - Node propertiesNode = propertiesList.item(j); - switch (propertiesNode.getNodeType()) - { - case Node.TEXT_NODE: - break; - case Node.ELEMENT_NODE: - m_scope = propertiesNode.getLocalName(); - break; - } - } - } - break; - } - } - } - } - - /** - * Execute the request - * - * @exception WebDAVServerException - */ - protected void executeImpl() throws WebDAVServerException, Exception - { - FileFolderService fileFolderService = getFileFolderService(); - String path = getPath(); - NodeRef rootNodeRef = getRootNodeRef(); - // Get the active user - String userName = getDAVHelper().getAuthenticationService().getCurrentUserName(); - - if (logger.isDebugEnabled()) - { - logger.debug("Locking node: \n" + - " user: " + userName + "\n" + - " path: " + path); - } - - FileInfo lockNodeInfo = null; - try - { - // Check if the path exists - lockNodeInfo = getDAVHelper().getNodeForPath(getRootNodeRef(), getPath(), m_request.getServletPath()); - } - catch (FileNotFoundException e) - { - // need to create it - String[] splitPath = getDAVHelper().splitPath(path); - // check - if (splitPath[1].length() == 0) - { - throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - - FileInfo dirInfo = null; - List dirPathElements = getDAVHelper().splitAllPaths(splitPath[0]); - if (dirPathElements.size() == 0) - { - // if there are no path elements we are at the root so get the root node - dirInfo = fileFolderService.getFileInfo(getRootNodeRef()); - } - else - { - // make sure folder structure is present - dirInfo = FileFolderUtil.makeFolders(fileFolderService, rootNodeRef, dirPathElements, ContentModel.TYPE_FOLDER); - } - - if (dirInfo == null) - { - throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - } - - // create the file - lockNodeInfo = fileFolderService.create(dirInfo.getNodeRef(), splitPath[1], ContentModel.TYPE_CONTENT); - - if (logger.isDebugEnabled()) - { - logger.debug("Created new node for lock: \n" + - " path: " + path + "\n" + - " node: " + lockNodeInfo); - } - - m_response.setStatus(HttpServletResponse.SC_CREATED); - } - - - - // Check if this is a new lock or a lock refresh - if (hasLockToken()) - { - this.lockInfo = checkNode(lockNodeInfo); - // Refresh an existing lock - refreshLock(lockNodeInfo, userName); - } - else - { - this.lockInfo = checkNode(lockNodeInfo, true, WebDAV.XML_EXCLUSIVE.equals(m_scope)); - // Create a new lock - createLock(lockNodeInfo, userName); - } - - - m_response.setHeader(WebDAV.HEADER_LOCK_TOKEN, "<" + WebDAV.makeLockToken(lockNodeInfo.getNodeRef(), userName) + ">"); - m_response.setHeader(WebDAV.HEADER_CONTENT_TYPE, WebDAV.XML_CONTENT_TYPE); - - // We either created a new lock or refreshed an existing lock, send back the lock details - generateResponse(lockNodeInfo.getNodeRef(), userName); - } - - /** - * Create a new lock - * - * @param lockNode NodeRef - * @param userName String - * @exception WebDAVServerException - */ - protected final void createLock(FileInfo lockNode, String userName) throws WebDAVServerException - { - LockService lockService = getLockService(); - - // Create Lock token - lockToken = WebDAV.makeLockToken(lockNode.getNodeRef(), userName); - - if (WebDAV.XML_EXCLUSIVE.equals(m_scope)) - { - // Lock the node - lockService.lock(lockNode.getNodeRef(), LockType.WRITE_LOCK, getLockTimeout()); - - //this.lockInfo.setToken(lockToken); - getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_OPAQUE_LOCK_TOKEN, lockToken); - } - else - { - this.lockInfo.addSharedLockToken(lockToken); - String sharedLockTokens = LockInfo.makeSharedLockTokensString(this.lockInfo.getSharedLockTokens()); - getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_SHARED_LOCK_TOKENS, sharedLockTokens); - - } - - // Store lock depth - getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_LOCK_DEPTH, WebDAV.getDepthName(m_depth)); - - // Store lock scope (shared/exclusive) - getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_LOCK_SCOPE, m_scope); - - } - - /** - * Refresh an existing lock - * - * @param lockNode NodeRef - * @param userName String - * @exception WebDAVServerException - */ - protected final void refreshLock(FileInfo lockNode, String userName) throws WebDAVServerException - { - LockService lockService = getLockService(); - - if (WebDAV.XML_EXCLUSIVE.equals(m_scope)) - { - // Update the expiry for the lock - lockService.lock(lockNode.getNodeRef(), LockType.WRITE_LOCK, getLockTimeout()); - } - } - - /** - * Generates the XML lock discovery response body - */ - protected void generateResponse(NodeRef lockNode, String userName) throws Exception - { - XMLWriter xml = createXMLWriter(); - - xml.startDocument(); - - String nsdec = generateNamespaceDeclarations(null); - xml.startElement(EMPTY_NS, WebDAV.XML_PROP + nsdec, WebDAV.XML_PROP + nsdec, - getDAVHelper().getNullAttributes()); - - // Output the lock details - generateLockDiscoveryXML(xml, lockNode); - - // Close off the XML - xml.endElement(EMPTY_NS, WebDAV.XML_PROP, WebDAV.XML_PROP); - - // Send the XML back to the client - xml.flush(); - } - - - /** - * Generates the lock discovery XML response - * - * @param xml XMLWriter - * @param lockNode NodeRef - */ - protected void generateLockDiscoveryXML(XMLWriter xml, NodeRef lockNode) throws Exception - { - Attributes nullAttr= getDAVHelper().getNullAttributes(); - - if (lockNode != null) - { - - // Get the lock details - - NodeService nodeService = getNodeService(); - - String owner = (String) nodeService.getProperty(lockNode, ContentModel.PROP_LOCK_OWNER); - Date expiryDate = (Date) nodeService.getProperty(lockNode, ContentModel.PROP_EXPIRY_DATE); - - // Output the XML response - - xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_DISCOVERY, WebDAV.XML_LOCK_DISCOVERY, nullAttr); - xml.startElement(EMPTY_NS, WebDAV.XML_ACTIVE_LOCK, WebDAV.XML_ACTIVE_LOCK, nullAttr); - - xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_LOCK_TYPE, nullAttr); - xml.write(DocumentHelper.createElement(WebDAV.XML_WRITE)); - xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_LOCK_TYPE); - - xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_LOCK_SCOPE, nullAttr); - if (lockToken != null) - { - // In case of lock creation take the scope from request header - xml.write(DocumentHelper.createElement(m_scope)); - } - else - { - // In case of lock refreshing take the scope from previously stored lock - xml.write(DocumentHelper.createElement(this.lockInfo.getScope())); - } - xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_LOCK_SCOPE); - - xml.startElement(EMPTY_NS, WebDAV.XML_DEPTH, WebDAV.XML_DEPTH, nullAttr); - xml.write(WebDAV.getDepthName(m_depth)); - xml.endElement(EMPTY_NS, WebDAV.XML_DEPTH, WebDAV.XML_DEPTH); - - xml.startElement(EMPTY_NS, WebDAV.XML_OWNER, WebDAV.XML_OWNER, nullAttr); - xml.write(owner); - xml.endElement(EMPTY_NS, WebDAV.XML_OWNER, WebDAV.XML_OWNER); - - xml.startElement(EMPTY_NS, WebDAV.XML_TIMEOUT, WebDAV.XML_TIMEOUT, nullAttr); - - // Output the expiry time - - String strTimeout = WebDAV.INFINITE; - if (expiryDate != null) - { - long timeoutRemaining = (expiryDate.getTime() - System.currentTimeMillis())/1000L; - - strTimeout = WebDAV.SECOND + timeoutRemaining; - } - xml.write(strTimeout); - - xml.endElement(EMPTY_NS, WebDAV.XML_TIMEOUT, WebDAV.XML_TIMEOUT); - - xml.startElement(EMPTY_NS, WebDAV.XML_LOCK_TOKEN, WebDAV.XML_LOCK_TOKEN, nullAttr); - xml.startElement(EMPTY_NS, WebDAV.XML_HREF, WebDAV.XML_HREF, nullAttr); - if (lockToken != null) - { - // Output created lock - xml.write(lockToken); - } - else - { - // Output refreshed lock - xml.write(this.lockInfo.getToken()); - } - xml.endElement(EMPTY_NS, WebDAV.XML_HREF, WebDAV.XML_HREF); - xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_TOKEN, WebDAV.XML_LOCK_TOKEN); - - xml.endElement(EMPTY_NS, WebDAV.XML_ACTIVE_LOCK, WebDAV.XML_ACTIVE_LOCK); - xml.endElement(EMPTY_NS, WebDAV.XML_LOCK_DISCOVERY, WebDAV.XML_LOCK_DISCOVERY); - } - } - - /** - * Generates a list of namespace declarations for the response - */ - protected String generateNamespaceDeclarations(HashMap nameSpaces) - { - StringBuilder ns = new StringBuilder(); - - ns.append(" "); - ns.append(WebDAV.XML_NS); - ns.append("=\""); - ns.append(WebDAV.DEFAULT_NAMESPACE_URI); - ns.append("\""); - - // Add additional namespaces - - if ( nameSpaces != null) - { - Iterator namespaceList = nameSpaces.keySet().iterator(); - - while (namespaceList.hasNext()) - { - String strNamespaceUri = namespaceList.next(); - String strNamespaceName = nameSpaces.get(strNamespaceUri); - - ns.append(" ").append(WebDAV.XML_NS).append(":").append(strNamespaceName).append("=\""); - ns.append(strNamespaceUri).append("\" "); - } - } - - return ns.toString(); - } - - -} + * along with Alfresco. If not, see . + */ +package org.alfresco.repo.webdav; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.model.ContentModel; +import org.alfresco.model.WebDAVModel; +import org.alfresco.service.cmr.lock.LockService; +import org.alfresco.service.cmr.lock.LockType; +import org.alfresco.service.cmr.model.FileFolderService; +import org.alfresco.service.cmr.model.FileFolderUtil; +import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.model.FileNotFoundException; +import org.alfresco.service.cmr.repository.NodeRef; +import org.dom4j.io.XMLWriter; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +/** + * Implements the WebDAV LOCK method + * + * @author gavinc + */ +public class LockMethod extends WebDAVMethod +{ + public static final String EMPTY_NS = ""; + + private int m_timeoutDuration = WebDAV.TIMEOUT_INFINITY; + + private LockInfo lockInfo = new LockInfo(); + + private boolean createExclusive; + + private String lockToken= null; + + /** + * Default constructor + */ + public LockMethod() + { + } + + /** + * Returns true if request has lock token in the If header + * + * @return boolean + */ + protected final boolean hasLockToken() + { + if (m_conditions != null) + { + for (Condition condition : m_conditions) + { + if (!condition.getLockTokensMatch().isEmpty()) + { + return true; + } + } + } + return false; + } + + /** + * Return the lock timeout, in minutes + * + * @return int + */ + protected final int getLockTimeout() + { + return m_timeoutDuration; + } + + /** + * Parse the request headers + * + * @exception WebDAVServerException + */ + protected void parseRequestHeaders() throws WebDAVServerException + { + // Get user Agent + + m_userAgent = m_request.getHeader(WebDAV.HEADER_USER_AGENT); + + // Get the depth + + parseDepthHeader(); + + // According to the specification: "Values other than 0 or infinity MUST NOT be used with the Depth header on a LOCK method.". + // The specification does not specify the error code for this case - so we use HttpServletResponse.SC_INTERNAL_SERVER_ERROR. + if (m_depth != WebDAV.DEPTH_0 && m_depth != WebDAV.DEPTH_INFINITY) + { + throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + // Parse Lock tokens and ETags, if any + + parseIfHeader(); + + // Get the lock timeout value + + String strTimeout = m_request.getHeader(WebDAV.HEADER_TIMEOUT); + + // If the timeout header starts with anything other than Second + // leave the timeout as the default + + if (strTimeout != null && strTimeout.startsWith(WebDAV.SECOND)) + { + try + { + // Some clients send header as Second-180 Seconds so we need to + // look for the space + + int idx = strTimeout.indexOf(" "); + + if (idx != -1) + { + // Get the bit after Second- and before the space + + strTimeout = strTimeout.substring(WebDAV.SECOND.length(), idx); + } + else + { + // The string must be in the correct format + + strTimeout = strTimeout.substring(WebDAV.SECOND.length()); + } + m_timeoutDuration = Integer.parseInt(strTimeout); + } + catch (Exception e) + { + // Warn about the parse failure and leave the timeout as the + // default + + logger.warn("Failed to parse Timeout header: " + strTimeout); + } + } + + // DEBUG + + if (logger.isDebugEnabled()) + logger.debug("Timeout=" + getLockTimeout() + ", depth=" + getDepth()); + } + + /** + * Parse the request body + * + * @exception WebDAVServerException + */ + protected void parseRequestBody() throws WebDAVServerException + { + if (m_request.getContentLength() == -1) + { + return; + } + + Document body = getRequestBodyAsDocument(); + if (body != null) + { + OUTER: for (Node currentNode = body.getDocumentElement().getFirstChild(); currentNode != null; currentNode = currentNode.getNextSibling()) + { + if (currentNode instanceof Element && WebDAV.DEFAULT_NAMESPACE_URI.equals(((Element) currentNode).getNamespaceURI()) + && WebDAV.XML_LOCK_SCOPE.equals(((Element) currentNode).getLocalName())) + { + for (Node propertiesNode = currentNode.getFirstChild(); propertiesNode != null; propertiesNode = propertiesNode.getNextSibling()) + { + if (propertiesNode instanceof Element && WebDAV.DEFAULT_NAMESPACE_URI.equals(((Element) propertiesNode).getNamespaceURI())) + { + this.createExclusive = WebDAV.XML_EXCLUSIVE.equals(propertiesNode.getLocalName()); + break OUTER; + } + } + break OUTER; + } + } + } + } + + /** + * Execute the request + * + * @exception WebDAVServerException + */ + protected void executeImpl() throws WebDAVServerException, Exception + { + FileFolderService fileFolderService = getFileFolderService(); + String path = getPath(); + NodeRef rootNodeRef = getRootNodeRef(); + // Get the active user + String userName = getDAVHelper().getAuthenticationService().getCurrentUserName(); + + if (logger.isDebugEnabled()) + { + logger.debug("Locking node: \n" + + " user: " + userName + "\n" + + " path: " + path); + } + + FileInfo lockNodeInfo = null; + try + { + // Check if the path exists + lockNodeInfo = getDAVHelper().getNodeForPath(getRootNodeRef(), getPath(), m_request.getServletPath()); + } + catch (FileNotFoundException e) + { + // need to create it + String[] splitPath = getDAVHelper().splitPath(path); + // check + if (splitPath[1].length() == 0) + { + throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + FileInfo dirInfo = null; + List dirPathElements = getDAVHelper().splitAllPaths(splitPath[0]); + if (dirPathElements.size() == 0) + { + // if there are no path elements we are at the root so get the root node + dirInfo = fileFolderService.getFileInfo(getRootNodeRef()); + } + else + { + // make sure folder structure is present + dirInfo = FileFolderUtil.makeFolders(fileFolderService, rootNodeRef, dirPathElements, ContentModel.TYPE_FOLDER); + } + + if (dirInfo == null) + { + throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + + // create the file + lockNodeInfo = fileFolderService.create(dirInfo.getNodeRef(), splitPath[1], ContentModel.TYPE_CONTENT); + + if (logger.isDebugEnabled()) + { + logger.debug("Created new node for lock: \n" + + " path: " + path + "\n" + + " node: " + lockNodeInfo); + } + + m_response.setStatus(HttpServletResponse.SC_CREATED); + } + + + + // Check if this is a new lock or a lock refresh + if (hasLockToken()) + { + this.lockInfo = checkNode(lockNodeInfo); + // If a request body is not defined and "If" header is sent we have createExclusive as false, + // but we need to check a previous LOCK was an exclusive. I.e. get the property for node. It + // is already has got in a checkNode method, so we need just get a scope from lockInfo. + // This particular case was raised as ALF-4008. + this.createExclusive = WebDAV.XML_EXCLUSIVE.equals(this.lockInfo.getScope()); + // Refresh an existing lock + refreshLock(lockNodeInfo, userName); + } + else + { + this.lockInfo = checkNode(lockNodeInfo, true, this.createExclusive); + // Create a new lock + createLock(lockNodeInfo, userName); + } + + + m_response.setHeader(WebDAV.HEADER_LOCK_TOKEN, "<" + WebDAV.makeLockToken(lockNodeInfo.getNodeRef(), userName) + ">"); + m_response.setHeader(WebDAV.HEADER_CONTENT_TYPE, WebDAV.XML_CONTENT_TYPE); + + // We either created a new lock or refreshed an existing lock, send back the lock details + generateResponse(lockNodeInfo.getNodeRef(), userName); + } + + /** + * Create a new lock + * + * @param lockNode NodeRef + * @param userName String + * @exception WebDAVServerException + */ + protected final void createLock(FileInfo lockNode, String userName) throws WebDAVServerException + { + LockService lockService = getLockService(); + + // Create Lock token + lockToken = WebDAV.makeLockToken(lockNode.getNodeRef(), userName); + + if (this.createExclusive) + { + // Lock the node + lockService.lock(lockNode.getNodeRef(), LockType.WRITE_LOCK, getLockTimeout()); + + //this.lockInfo.setToken(lockToken); + getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_OPAQUE_LOCK_TOKEN, lockToken); + } + else + { + this.lockInfo.addSharedLockToken(lockToken); + String sharedLockTokens = LockInfo.makeSharedLockTokensString(this.lockInfo.getSharedLockTokens()); + getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_SHARED_LOCK_TOKENS, sharedLockTokens); + + } + + // Store lock depth + getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_LOCK_DEPTH, WebDAV.getDepthName(m_depth)); + + // Store lock scope (shared/exclusive) + getNodeService().setProperty(lockNode.getNodeRef(), WebDAVModel.PROP_LOCK_SCOPE, this.createExclusive ? WebDAV.XML_EXCLUSIVE : WebDAV.XML_SHARED); + + } + + /** + * Refresh an existing lock + * + * @param lockNode NodeRef + * @param userName String + * @exception WebDAVServerException + */ + private final void refreshLock(FileInfo lockNode, String userName) throws WebDAVServerException + { + if (this.createExclusive) + { + // Update the expiry for the lock + getLockService().lock(lockNode.getNodeRef(), LockType.WRITE_LOCK, getLockTimeout()); + } + } + + /** + * Generates the XML lock discovery response body + */ + private void generateResponse(NodeRef lockNode, String userName) throws Exception + { + String scope; + String lt; + if (lockToken != null) + { + // In case of lock creation take the scope from request header + scope = this.createExclusive ? WebDAV.XML_EXCLUSIVE : WebDAV.XML_SHARED; + // Output created lock + lt = lockToken; + } + else + { + // In case of lock refreshing take the scope from previously stored lock + scope = this.lockInfo.getScope(); + // Output refreshed lock + lt = this.lockInfo.getToken(); + } + String owner = (String) getNodeService().getProperty(lockNode, ContentModel.PROP_LOCK_OWNER); + + XMLWriter xml = createXMLWriter(); + + xml.startDocument(); + + // Output the lock details + String nsdec = generateNamespaceDeclarations(null); + + if (WebDAV.AGENT_MS_6_1_7600.equals(m_userAgent)) + { + xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROP + nsdec, WebDAV.XML_NS_PROP + nsdec, getDAVHelper().getNullAttributes()); + + // Output the lock details + generateLockDiscoveryXML(xml, lockNode, false, scope, WebDAV.getDepthName(m_depth), lt, owner); + + // Close off the XML + xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP); + + } + else + { + xml.startElement(EMPTY_NS, WebDAV.XML_PROP + nsdec, WebDAV.XML_PROP + nsdec, getDAVHelper().getNullAttributes()); + + // Output the lock details + generateLockDiscoveryXML(xml, lockNode, true, scope, WebDAV.getDepthName(m_depth), lt, owner); + + // Close off the XML + xml.endElement(EMPTY_NS, WebDAV.XML_PROP, WebDAV.XML_PROP); + } + + // Send the XML back to the client + xml.flush(); + } + + + /** + * Generates a list of namespace declarations for the response + */ + protected String generateNamespaceDeclarations(HashMap nameSpaces) + { + StringBuilder ns = new StringBuilder(); + + ns.append(" "); + ns.append(WebDAV.XML_NS); + ns.append("=\""); + ns.append(WebDAV.DEFAULT_NAMESPACE_URI); + ns.append("\""); + + // Add additional namespaces + + if ( nameSpaces != null) + { + Iterator namespaceList = nameSpaces.keySet().iterator(); + + while (namespaceList.hasNext()) + { + String strNamespaceUri = namespaceList.next(); + String strNamespaceName = nameSpaces.get(strNamespaceUri); + + ns.append(" ").append(WebDAV.XML_NS).append(":").append(strNamespaceName).append("=\""); + ns.append(strNamespaceUri).append("\" "); + } + } + + return ns.toString(); + } + + +} diff --git a/source/java/org/alfresco/repo/webdav/PropFindMethod.java b/source/java/org/alfresco/repo/webdav/PropFindMethod.java index d4d3187cfa..520c736589 100644 --- a/source/java/org/alfresco/repo/webdav/PropFindMethod.java +++ b/source/java/org/alfresco/repo/webdav/PropFindMethod.java @@ -18,6 +18,7 @@ */ package org.alfresco.repo.webdav; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; @@ -46,6 +47,7 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.Attributes; +import org.xml.sax.SAXException; import org.xml.sax.helpers.AttributesImpl; /** @@ -908,13 +910,10 @@ public class PropFindMethod extends WebDAVMethod xml.startElement(WebDAV.DAV_NS, WebDAV.XML_SUPPORTED_LOCK, WebDAV.XML_NS_SUPPORTED_LOCK, nullAttr); - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE, nullAttr); - xml.write(DocumentHelper.createElement(WebDAV.XML_NS_EXCLUSIVE)); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE); - - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE, nullAttr); - xml.write(DocumentHelper.createElement(WebDAV.XML_NS_WRITE)); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE); + // Output exclusive lock + writeLock(xml, WebDAV.XML_NS_EXCLUSIVE); + // Output shared lock + writeLock(xml, WebDAV.XML_NS_SHARED); xml.endElement(WebDAV.DAV_NS, WebDAV.XML_SUPPORTED_LOCK, WebDAV.XML_NS_SUPPORTED_LOCK); } @@ -923,4 +922,27 @@ public class PropFindMethod extends WebDAVMethod throw new AlfrescoRuntimeException("XML write error", ex); } } + + /** + * Output the lockentry element of the specified type + * @param xml XMLWriter + * @param lockType lock type. Can be WebDAV.XML_NS_EXCLUSIVE or WebDAV.XML_NS_SHARED + * @param lockType lock type containing namespace + * @throws SAXException + * @throws IOException + */ + private void writeLock(XMLWriter xml, String lockType) throws SAXException, IOException + { + AttributesImpl nullAttr = getDAVHelper().getNullAttributes(); + + xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_ENTRY, WebDAV.XML_NS_LOCK_ENTRY, nullAttr); + xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE, nullAttr); + xml.write(DocumentHelper.createElement(lockType)); + xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE); + + xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE, nullAttr); + xml.write(DocumentHelper.createElement(WebDAV.XML_NS_WRITE)); + xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE); + xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_ENTRY, WebDAV.XML_NS_LOCK_ENTRY); + } } diff --git a/source/java/org/alfresco/repo/webdav/PropPatchMethod.java b/source/java/org/alfresco/repo/webdav/PropPatchMethod.java index 176be00c22..ac62ab176a 100644 --- a/source/java/org/alfresco/repo/webdav/PropPatchMethod.java +++ b/source/java/org/alfresco/repo/webdav/PropPatchMethod.java @@ -172,7 +172,8 @@ public class PropPatchMethod extends PropFindMethod @Override protected void parseRequestHeaders() throws WebDAVServerException { - // Nothing to do in this method + // Parse Lock tokens and ETags, if any + parseIfHeader(); } /** diff --git a/source/java/org/alfresco/repo/webdav/UnlockMethod.java b/source/java/org/alfresco/repo/webdav/UnlockMethod.java index 0ec5363e09..43884d63f2 100644 --- a/source/java/org/alfresco/repo/webdav/UnlockMethod.java +++ b/source/java/org/alfresco/repo/webdav/UnlockMethod.java @@ -22,6 +22,7 @@ import java.util.LinkedList; import javax.servlet.http.HttpServletResponse; +import org.alfresco.model.ContentModel; import org.alfresco.model.WebDAVModel; import org.alfresco.service.cmr.lock.LockService; import org.alfresco.service.cmr.lock.LockStatus; @@ -140,8 +141,11 @@ public class UnlockMethod extends WebDAVMethod LockStatus lockSts = lockService.getLockStatus(lockNodeInfo.getNodeRef()); if (lockSts == LockStatus.LOCK_OWNER) { - // Unlock the node - lockService.unlock(lockNodeInfo.getNodeRef()); + // Unlock the node if it is not a Working Copy (ALF-4479) + if (!nodeService.hasAspect(lockNodeInfo.getNodeRef(), ContentModel.ASPECT_WORKING_COPY)) + { + lockService.unlock(lockNodeInfo.getNodeRef()); + } nodeService.removeProperty(lockNodeInfo.getNodeRef(), WebDAVModel.PROP_OPAQUE_LOCK_TOKEN); nodeService.removeProperty(lockNodeInfo.getNodeRef(), WebDAVModel.PROP_LOCK_DEPTH); nodeService.removeProperty(lockNodeInfo.getNodeRef(), WebDAVModel.PROP_LOCK_SCOPE); diff --git a/source/java/org/alfresco/repo/webdav/WebDAV.java b/source/java/org/alfresco/repo/webdav/WebDAV.java index 9134e4faea..df49f8e50f 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAV.java +++ b/source/java/org/alfresco/repo/webdav/WebDAV.java @@ -114,6 +114,7 @@ public class WebDAV public static final String HEADER_OVERWRITE = "Overwrite"; public static final String HEADER_RANGE = "Range"; public static final String HEADER_TIMEOUT = "Timeout"; + public static final String HEADER_USER_AGENT = "User-Agent"; // If-Modified/If-Unmodified date format @@ -123,6 +124,10 @@ public class WebDAV public static final String HEADER_KEY_NOT = "Not"; + // User agents + + public static final String AGENT_MS_6_1_7600 = "Microsoft-WebDAV-MiniRedir/6.1.7600"; + // General string constants public static final String ASTERISK = "*"; @@ -158,6 +163,7 @@ public class WebDAV public static final String XML_GET_LAST_MODIFIED = "getlastmodified"; public static final String XML_HREF = "href"; public static final String XML_LOCK_DISCOVERY = "lockdiscovery"; + public static final String XML_LOCK_ENTRY = "lockentry"; public static final String XML_LOCK_SCOPE = "lockscope"; public static final String XML_LOCK_TOKEN = "locktoken"; public static final String XML_LOCK_TYPE = "locktype"; @@ -194,6 +200,7 @@ public class WebDAV public static final String XML_NS_GET_LAST_MODIFIED = DAV_NS_PREFIX + "getlastmodified"; public static final String XML_NS_HREF = DAV_NS_PREFIX + "href"; public static final String XML_NS_LOCK_DISCOVERY = DAV_NS_PREFIX + "lockdiscovery"; + public static final String XML_NS_LOCK_ENTRY = DAV_NS_PREFIX + "lockentry"; public static final String XML_NS_LOCK_SCOPE = DAV_NS_PREFIX + "lockscope"; public static final String XML_NS_LOCK_TOKEN = DAV_NS_PREFIX + "locktoken"; public static final String XML_NS_LOCK_TYPE = DAV_NS_PREFIX + "locktype"; diff --git a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java index fd0b65a23c..a6d7c54690 100644 --- a/source/java/org/alfresco/repo/webdav/WebDAVMethod.java +++ b/source/java/org/alfresco/repo/webdav/WebDAVMethod.java @@ -106,6 +106,9 @@ public abstract class WebDAVMethod protected String m_strPath = null; + // User Agent + + protected String m_userAgent = null; // If header conditions @@ -691,16 +694,34 @@ public abstract class WebDAVMethod return writer; } - /** + /** * Generates the lock discovery XML response * * @param xml XMLWriter * @param lockNode NodeRef */ protected void generateLockDiscoveryXML(XMLWriter xml, NodeRef lockNode, LockInfo lockInfo) throws Exception + { + String owner = (String) getNodeService().getProperty(lockNode, ContentModel.PROP_LOCK_OWNER); + generateLockDiscoveryXML(xml, lockNode, false, lockInfo.getScope(), lockInfo.getDepth(), WebDAV.makeLockToken(lockNode, owner), owner); + } + + /** + * Generates the lock discovery XML response + * + * @param xml XMLWriter + * @param lockNode NodeRef + * @param emptyNamespace boolean True if namespace should be empty. Used to avoid bugs in WebDAV clients. + * @param scope String lock scope + * @param depth String lock depth + * @param lToken String locktoken + * @param owner String lock owner + * + */ + protected void generateLockDiscoveryXML(XMLWriter xml, NodeRef lockNode, boolean emptyNamespace, String scope, String depth, String lToken, String owner) throws Exception { Attributes nullAttr= getDAVHelper().getNullAttributes(); - + String ns = emptyNamespace ? "" : WebDAV.DAV_NS; if (lockNode != null) { @@ -708,35 +729,32 @@ public abstract class WebDAVMethod NodeService nodeService = getNodeService(); - String owner = (String) nodeService.getProperty(lockNode, ContentModel.PROP_LOCK_OWNER); Date expiryDate = (Date) nodeService.getProperty(lockNode, ContentModel.PROP_EXPIRY_DATE); // Output the XML response - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_DISCOVERY, WebDAV.XML_NS_LOCK_DISCOVERY, nullAttr); - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_ACTIVE_LOCK, WebDAV.XML_NS_ACTIVE_LOCK, nullAttr); + xml.startElement(ns, WebDAV.XML_LOCK_DISCOVERY, emptyNamespace ? WebDAV.XML_LOCK_DISCOVERY : WebDAV.XML_NS_LOCK_DISCOVERY, nullAttr); + xml.startElement(ns, WebDAV.XML_ACTIVE_LOCK, emptyNamespace ? WebDAV.XML_ACTIVE_LOCK : WebDAV.XML_NS_ACTIVE_LOCK, nullAttr); - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE, nullAttr); - xml.write(DocumentHelper.createElement(WebDAV.XML_NS_WRITE)); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE); + xml.startElement(ns, WebDAV.XML_LOCK_TYPE, emptyNamespace ? WebDAV.XML_LOCK_TYPE : WebDAV.XML_NS_LOCK_TYPE, nullAttr); + xml.write(DocumentHelper.createElement(emptyNamespace ? WebDAV.XML_WRITE : WebDAV.XML_NS_WRITE)); + xml.endElement(ns, WebDAV.XML_LOCK_TYPE, emptyNamespace ? WebDAV.XML_LOCK_TYPE : WebDAV.XML_NS_LOCK_TYPE); - // NOTE: We only do exclusive lock tokens at the moment - - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE, nullAttr); - xml.write(DocumentHelper.createElement(lockInfo.getScope())); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE); + xml.startElement(ns, WebDAV.XML_LOCK_SCOPE, emptyNamespace ? WebDAV.XML_LOCK_SCOPE : WebDAV.XML_NS_LOCK_SCOPE, nullAttr); + xml.write(DocumentHelper.createElement(scope)); + xml.endElement(ns, WebDAV.XML_LOCK_SCOPE, emptyNamespace ? WebDAV.XML_LOCK_SCOPE : WebDAV.XML_NS_LOCK_SCOPE); // NOTE: We only support one level of lock at the moment - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_DEPTH, WebDAV.XML_NS_DEPTH, nullAttr); - xml.write(lockInfo.getDepth()); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_DEPTH, WebDAV.XML_NS_DEPTH); + xml.startElement(ns, WebDAV.XML_DEPTH, emptyNamespace ? WebDAV.XML_DEPTH : WebDAV.XML_NS_DEPTH, nullAttr); + xml.write(depth); + xml.endElement(ns, WebDAV.XML_DEPTH, emptyNamespace ? WebDAV.XML_DEPTH : WebDAV.XML_NS_DEPTH); - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_OWNER, WebDAV.XML_NS_OWNER, nullAttr); + xml.startElement(ns, WebDAV.XML_OWNER, emptyNamespace ? WebDAV.XML_OWNER : WebDAV.XML_NS_OWNER, nullAttr); xml.write(owner); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_OWNER, WebDAV.XML_NS_OWNER); + xml.endElement(ns, WebDAV.XML_OWNER, emptyNamespace ? WebDAV.XML_OWNER : WebDAV.XML_NS_OWNER); - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_TIMEOUT, WebDAV.XML_NS_TIMEOUT, nullAttr); + xml.startElement(ns, WebDAV.XML_TIMEOUT, emptyNamespace ? WebDAV.XML_TIMEOUT : WebDAV.XML_NS_TIMEOUT, nullAttr); // Output the expiry time @@ -749,18 +767,18 @@ public abstract class WebDAVMethod } xml.write(strTimeout); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_TIMEOUT, WebDAV.XML_NS_TIMEOUT); + xml.endElement(ns, WebDAV.XML_TIMEOUT, emptyNamespace ? WebDAV.XML_TIMEOUT : WebDAV.XML_NS_TIMEOUT); - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TOKEN, WebDAV.XML_NS_LOCK_TOKEN, nullAttr); - xml.startElement(WebDAV.DAV_NS, WebDAV.XML_HREF, WebDAV.XML_NS_HREF, nullAttr); + xml.startElement(ns, WebDAV.XML_LOCK_TOKEN, emptyNamespace ? WebDAV.XML_LOCK_TOKEN : WebDAV.XML_NS_LOCK_TOKEN, nullAttr); + xml.startElement(ns, WebDAV.XML_HREF, emptyNamespace ? WebDAV.XML_HREF : WebDAV.XML_NS_HREF, nullAttr); - xml.write(WebDAV.makeLockToken(lockNode, owner)); + xml.write(lToken); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_HREF, WebDAV.XML_NS_HREF); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TOKEN, WebDAV.XML_NS_LOCK_TOKEN); + xml.endElement(ns, WebDAV.XML_HREF, emptyNamespace ? WebDAV.XML_HREF : WebDAV.XML_NS_HREF); + xml.endElement(ns, WebDAV.XML_LOCK_TOKEN, emptyNamespace ? WebDAV.XML_LOCK_TOKEN : WebDAV.XML_NS_LOCK_TOKEN); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_ACTIVE_LOCK, WebDAV.XML_NS_ACTIVE_LOCK); - xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_DISCOVERY, WebDAV.XML_NS_LOCK_DISCOVERY); + xml.endElement(ns, WebDAV.XML_ACTIVE_LOCK, emptyNamespace ? WebDAV.XML_ACTIVE_LOCK : WebDAV.XML_NS_ACTIVE_LOCK); + xml.endElement(ns, WebDAV.XML_LOCK_DISCOVERY, emptyNamespace ? WebDAV.XML_LOCK_DISCOVERY : WebDAV.XML_NS_LOCK_DISCOVERY); } } diff --git a/source/java/org/alfresco/web/app/servlet/HTTPProxy.java b/source/java/org/alfresco/web/app/servlet/HTTPProxy.java index 89ffa6f6d7..65b08f3622 100644 --- a/source/java/org/alfresco/web/app/servlet/HTTPProxy.java +++ b/source/java/org/alfresco/web/app/servlet/HTTPProxy.java @@ -63,6 +63,7 @@ public class HTTPProxy throws IOException { HttpURLConnection connection = (HttpURLConnection)url.openConnection(); + setRequestHeaders(connection); initialiseResponse(connection); InputStream input = connection.getInputStream(); OutputStream output = response.getOutputStream(); @@ -117,6 +118,15 @@ public class HTTPProxy } } + /** + * Set request headers + * + * @param urlConnection url connection + */ + protected void setRequestHeaders(URLConnection urlConnection) + { + } + /** * Write response *