source: publico/SDE/trunk/StrDoc.py @ 816

Última Alteração nesse arquivo desde 816 foi 816, incluída por ciciliati, 14 anos atrás

v101: Merge das versões v003 e v100. Ainda falta resolver os problemas

que surgiram na v003, especialmente no tratamento de eventos.

File size: 19.2 KB
Linha 
1# -*- coding: iso-8859-1 -*-
2
3"""
4from OFS.SimpleItem import SimpleItem
5from Globals import Persistent
6from Acquisition import Implicit
7"""
8from OFS.OrderedFolder import OrderedFolder
9from Products.ZCatalog.CatalogAwareness import CatalogAware
10from OFS.ObjectManager import ObjectManager
11from OFS.PropertyManager import PropertyManager
12import string
13
14def StrDoc_addForm(self, REQUEST):
15    "HTML para adicionar um novo objeto StrDoc"
16    return """
17<HTML>
18<HEAD><TITLE>Add StructuredDocument</TITLE></HEAD>
19<BODY BGCOLOR="#FFFFFF" LINK="#000099" VLINK="#555555">
20<H2>Add StructuredDocument</H2>
21<form action="manage_addStrDoc"><table>
22<tr><th>Id</th>
23    <td><input type=text name=id></td>
24</tr>
25<tr><th>Template Path</th>
26    <td><input type=text name="template_path"></td>
27</tr>
28<tr><th>Document Type</th>
29    <td><input type=text name="type"></td>
30</tr>
31<tr><td></td><td><input type=submit value=" Add "></td></tr>
32</table></form>
33</body></html>
34"""
35
36def StrDoc_add(self,REQUEST):
37    "Método para adicionar um objeto StrDoc"
38    instance = StrDoc(REQUEST)
39    instance.reindex_object()
40    self._setObject(REQUEST.id,instance)
41    return instance
42
43class StrDoc(OrderedFolder,CatalogAware):
44    "Classe de documentos estruturados"
45    meta_type = 'SDE-Document'
46    filtered_meta_types = []
47
48    def __init__(self,REQUEST):
49        self.id = REQUEST.id
50        self._setProperty("template_path",REQUEST.template_path)
51        self._setProperty("type",REQUEST.type)
52        self._setProperty("nextElemId",1)
53
54    # *** addChild
55    def addChild (self,ch_type='',ch_position='',obj=''):
56        request = self.REQUEST
57        RESPONSE =  request.RESPONSE
58        if obj:
59            self=obj
60        if ch_type:
61            request.set('type',ch_type)
62        if ch_position:
63            request.set('position',int(ch_position))
64        newElem = self.manage_addProduct['StructuredDoc'].StrDocElem_add(request)
65        return newElem.id
66
67    def addChildFromClipboard (self,ch_position='',obj=''):
68        request = self.REQUEST
69        session = request.SESSION
70        if session.has_key('SDE_clip_key'):
71            if session['SDE_clip_key']:
72                if obj:
73                    self=obj
74                clip_type = session['SDE_clip_type']     
75                self.manage_pasteObjects(session['SDE_clip_key'])
76                session['SDE_clip_type'] = ''
77                session['SDE_clip_key'] = ''
78                session['SDE_clip_object_type'] = ''
79                #if clip_type == 'CUT':
80                #    pass   
81                #elif clip_type == 'COPY':
82                #    pass
83                #    # No caso de cópia: recriar IDs, verificar se objetos-filho são diferentes
84                #    #self.setNewIdForChildren(recursive=1,obj=self)
85        return
86
87    # *** checksum
88    def checksum (self, obj=''):
89        "Método que calcula um checksum do conteúdo do documento estruturado"
90        from zlib import crc32
91        if obj:
92            self=obj
93        crc = 0L
94        i = 0
95        t = 0
96        for x in self.objectValues():
97            i = i + 1
98            crc = crc + (i * x.checksum(x))
99            t = t + i
100        if (i > 0):
101            crc = crc / t
102        else:
103            crc = 0L
104        if (self.meta_type == 'SDE-Document-Element'):
105            crc = crc + crc32(self.id + self.text)
106        return crc
107
108    # *** definitionElement
109    def definitionElement(self,element_path='',obj=''):
110        if obj:
111            self = obj
112        if element_path == '':
113            element_path = self.definitionPath(0)
114        subtree = string.split(element_path,"/")
115        temp_name = subtree.pop(0)
116        return self.template().getDefElement(subtree=subtree)
117
118    # *** definitionPath
119    def definitionPath(self,absolute=0):
120        if absolute:
121            return self.template_path + "/" + self.type
122        else:
123            return self.type
124
125    # *** delChild
126    def delChild(self):
127        request = self.REQUEST
128        RESPONSE = request.RESPONSE
129        if request.has_key ('id'):
130            self.manage_delObjects(request.id)
131        return RESPONSE.redirect (self.document().absolute_url() + "/renderHTMLforEditing")
132
133    # *** document
134    def document(self):
135      # return container.this() *** this was the ZClass version.
136        return self.this()
137
138    # *** getElements
139    def getElements(self,type='',obj=''):
140        if obj:
141            self = obj
142        result = []
143        for x in self.objectValues('SDE-Document-Element'):
144            if (not type) or (x.type == type):
145                result.append(x)
146            temp = x.getElements(type,obj=x)
147            if temp != []:
148                result.extend(temp)
149        return result
150
151    # *** getXML
152    def getXML(self,xsl=''):
153        tpt = self.template()
154        pref = tpt.xmlns_prefix
155        tag = tpt.xmlTag()
156        server = self.REQUEST['SERVER_URL']
157        printed = ''
158        printed+= "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"   # generalizar o encoding
159        if xsl:
160            if (xsl!="__default__"):
161                printed+= "<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>\n" % xsl
162            elif (tpt.default_xslt_for_html):
163                printed+= "<?xml-stylesheet type=\"text/xsl\" href=\"%s\"?>\n" % tpt.default_xslt_for_html
164        printed+= "<%s:%s id=\"%s\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" %(pref,tag,self.id)
165        printed+= "       xmlns:%s=\"/XSD/%s\"" % (pref, self.type)
166        printed+= "       xsi:noNamespaceSchemaLocation=\"/XSD/%s.xsd\">" % self.type
167        for x in (self.objectValues("SDE-Document-Element")):
168            printed+= x.renderXML("   ")
169        printed+= "</%s:%s>" % (pref,tag)
170        return printed
171
172    # *** isInvalid
173    def isInvalid(self,obj=''):
174        if obj:
175            self = obj
176        request = self.REQUEST
177        RESPONSE = request.RESPONSE
178        tpt = self.definitionElement(obj=self).objectValues(['SDE-Template-Element','SDE-Template-Link'])
179        doc = self.objectValues('SDE-Document-Element')
180        exc = []
181        if ((len(doc) == 0) and (self.meta_type == 'SDE-Document')):
182            exc.append ("Documento Inválido: Está Vazio.")
183        if (len(exc) == 0):
184            it = 0
185            max_it = len(tpt)
186            instance_found = 0
187            for e in doc:
188                while ((e.type != tpt[it].id) and (it < max_it)):
189                    if ((not tpt[it].isOptional()) and (not instance_found) and \
190                       (e.definitionElement(obj=e).exclusivity_group == -1)):
191                        exc.append ("Verificando \"%s\": Elemento obrigatório, \"%s\", não foi encontrado antes \
192                                     do elemento \"%s\"" % (self.type, tpt[it].id,e.type))
193                    it = it + 1
194                    instance_found = 0
195                if (e.type == tpt[it].id):
196                    if (instance_found and (not tpt[it].isMultiple())):
197                        exc.append ("Verificando \"%s\": O elemento \"%s\" não admite mais de uma ocorrência \
198                                     nesse contexto." % (self.type,tpt[it].id))
199                    instance_found = 1
200            while (it < max_it):
201                if (not instance_found) and (not tpt[it].isOptional() and (tpt[it].exclusivity_group == -1)):
202                    exc.append ("Verificando \"%s\": Elemento obrigatório, \"%s\", não foi encontrado após o \
203                                 último elemento." % (self.type,tpt[it].id))
204                it = it + 1
205                instance_found = 0
206        if (len(exc) == 0):
207            for e in doc:
208                exc_child = e.isInvalid(obj=e)
209                if (len(exc_child) > 0):
210                    for x in exc_child:
211                        exc.append (x)
212        return exc
213
214    # *** newElemId
215    def newElemId(self):
216        newId = "SDE" + str(self.nextElemId)
217        self.manage_changeProperties(nextElemId= int(self.nextElemId) + 1)
218        return newId
219
220    # *** possibleChild
221    def possibleChild(self,debug=0,obj=''):
222        "***debug***"
223        if obj:
224            self=obj
225        elmdef = self.definitionElement(obj=self)
226        tpt = elmdef.possibleChild(obj=elmdef)
227
228        #***
229        if debug:
230            print "<html><body>"
231            print tpt
232            print "<hr>"
233        #***
234
235        doc = []
236        for x in self.objectValues():
237            elm = []
238            elm.append(x.type)
239            elm.append(x.id)
240            elm.append(self.getObjectPosition(x.id))
241            elm.append(x.definitionElement(obj=x).exclusivity_group)
242            doc.append (elm)
243
244        #***
245        if debug:
246            print doc
247            print "<hr>"
248        #***
249
250        excl_grp = []
251        chd = []
252        i = 0
253        pos = 0
254        m = len(tpt)
255        jump = ""
256        for x in doc:
257            if (x[0] == jump):
258                chd[-1][1] = (x[2] + 1)
259                pos = pos + 1
260                continue
261            elif (x[3] != -1):
262                excl_grp.append (x[3])
263            jump = x[0]
264            while (i < m) and (x[0] != tpt[i][0]):
265                if tpt[i][4] not in excl_grp:
266                    elm = []
267                    elm.append (tpt[i][0])
268                    elm.append (pos)
269                    elm.append (tpt[i][5])
270                    elm.append (tpt[i][1])
271                    chd.append (elm)
272                i = i + 1
273            pos = x[2]
274            if (i < m):
275                pos = pos + 1
276                if (tpt[i][2]):
277                    elm = []
278                    elm.append (tpt[i][0])
279                    elm.append (pos)
280                    elm.append (tpt[i][5])
281                    elm.append ((1==1))
282                    chd.append (elm)
283            i = i + 1
284        while (i < m):
285            if tpt[i][4] not in excl_grp:
286                elm = []
287                elm.append (tpt[i][0])
288                elm.append (pos)
289                elm.append (tpt[i][5])
290                elm.append (tpt[i][1])
291                chd.append (elm)
292            i = i + 1
293
294        #***
295        if debug:
296            print excl_grp
297            print "<hr>"
298            print chd
299            print "<hr>"
300            print "</body></html>"
301            return chd
302        else:
303            return chd
304        #***
305
306    # *** possibleChildDebug
307    def possibleChildDebug(self):
308        return self.possibleChild(debug=1)
309
310    # *** renderHTML
311    def renderHTML(self):
312        "Renderiza o documento em HTML para visualização. Útil para browsers que não suportam XML."
313        printed=""
314        printed+= "<html>\n"
315        for x in (self.objectValues()):
316            printed+= x.renderHTML()
317        printed+= "\n</html>"
318        return printed
319
320    # *** renderHTMLforEditing
321    def renderHTMLforEditing(self,validation=0,REQUEST=None):
322        "Renderiza o documento em HTML para Edição. Útil para browsers que não suportam XML."
323        printed=""
324        request = REQUEST
325        if not request.AUTHENTICATED_USER.has_permission('EditStructuredDocument',self):
326            return self.renderHTML()
327        elem_id = ""
328        if request.has_key("elem_id"):
329            elem_id = request.elem_id
330        printed+= "<html>\n"
331        printed+= "<head>"
332        printed+= "    <script type=\"text/javascript\">"
333        printed+= "        function AddChildOnSelect (strContext, selSelectObject)"
334        printed+= "        {"
335        printed+= "            if (selSelectObject.options[selSelectObject.selectedIndex].value != \"\")"
336        printed+= "            {"
337        printed+= "                location.href=(strContext + '/renderHTMLforEditing_addChild?opt=' + \
338                                   selSelectObject.options[selSelectObject.selectedIndex].value)"
339        printed+= "            }"
340        printed+= "        }"
341        printed+= "    </script>"
342        printed+= "    <style>"
343        printed+= "        a.elem:link     { text-decoration:none; color: blue; }"
344        printed+= "        a.elem:visited  { text-decoration:none; color: blue; }"
345        printed+= "        a.elem:hover    { text-decoration:underline; color: red; }"
346        printed+= "    </style>"
347        printed+= "</head>\n"
348        printed+= "<body style=\"font-family: \'times new roman\'; font-size: 12pt;\">\n"
349        if elem_id == "":
350            printed+= "<form method=\"post\" action=\"%s/save\">\n" % self.absolute_url()
351            tmpObjs = self.possibleChild()
352            if (tmpObjs != []):
353                printed+= "    <select name=\"selChild\" onChange=AddChildOnSelect('%s',this)>" % self.absolute_url()
354                printed+= "        <option selected>Inserir filho...</option>"
355                opt = 0
356                for obj in tmpObjs:
357                    printed+= "        <option value=\"%i\">%s</option>" % (opt, obj[2])
358                    opt = opt + 1
359                printed+= "    </select>"
360            printed+= "</form>"
361        else:
362            printed+= "<p><a href=\"renderHTMLforEditing\">(Raiz)</a></p>"
363        for x in (self.objectValues()):
364            printed+= x.renderHTMLforEditing(indent=0,elem_id=elem_id)
365        if (validation):
366            printed+= "<hr>"
367            printed+= "<h3>Validação do Documento</h3>"
368            errors = self.isInvalid()
369            if (errors):
370                printed+= "<ul>"
371                for e in errors:
372                    printed+= "<li>%s</li>" % e
373                printed+= "</ul>"
374            else:
375                printed+= "Documento Válido."
376        printed+= "\n</body>"
377        printed+= "\n</html>"
378        return printed
379
380    # *** renderHTMLforEditing
381    def renderHTMLforEditing_addChild(self,REQUEST):
382        "Método para adicionar elementos ao documento, usando a interface renderHTML."
383        request = REQUEST
384        RESPONSE = request.RESPONSE
385        option = string.atoi(request.opt)
386        chd = self.possibleChild()[option]
387        request.set ('type',chd[0])
388        request.set ('position',chd[1])
389        newElemId = self.addChild()
390        return RESPONSE.redirect (self.document().absolute_url() + "/renderHTMLforEditing?elem_id=" + \
391                                  newElemId + "#" + newElemId)
392
393    # *** renderXML
394    def renderXML(self,xsl=''):
395        "Renderiza o documento em XML, de acordo com a estrutura definida no modelo."
396        printed = self.getXML(xsl)
397        self.REQUEST.RESPONSE.setHeader('Content-type', 'text/xml')
398        return printed
399
400    def renderXMLforEditing(self,xslt=None, action=None, p_type=None, p_pos=None, p_id=None, p_path=None):
401        """ Renderiza o documento em XML, em estrutura especial para edição.
402        'action'   parameters             description
403        EDIT       p_id                   renders the sd_element which has (id=p_id) with the attribute editing='yes'
404        MOVE_UP    p_path, p_id           move one position up the element identified by p_id located at p_path
405        MOVE_DOWN  p_path, p_id           move one position down the element identified by p_id located at p_path
406        CREATE     p_path, p_type, p_pos  creates, under the element p_path, a child of type p_type at the p_pos position
407        DELETE     p_path, p_id           removes the element p_id located in p_path
408        SAVE       p_path, p_id, REQUEST  saves the changes to the element p_id located in p_path
409                                          in REQUEST object there shall be a form called 'form_edit' containing
410                                          a object (textarea) called 'txa_text' and several objects (text) named
411                                          tat_??????, where ?????? is an attribute name (sde_attr)
412        CUT        p_path, p_id           mark as 'cut' the element identified by p_id located at p_path and put it and
413                                          its subtree into the clipboard
414        COPY       p_path, p_id           put a copy of the referred element and its subtree into the clipboard
415        PASTE      p_path, p_pos          put the contents of the clipboard under the element p_path """
416        request = self.REQUEST
417        response = request.RESPONSE
418        printed=""
419
420        if (action == 'CREATE'):
421            e = self.restrictedTraverse(p_path)
422            p_id = e.addChild (p_type, int(p_pos),obj=e)
423            action = 'EDIT'
424        elif (action == 'DELETE'):
425            e = self.restrictedTraverse(p_path)
426            e.manage_delObjects(p_id)
427        elif (action == 'SAVE'):
428            from Products.PythonScripts.standard import html_quote
429            e = self.restrictedTraverse(p_path + p_id)
430            e.manage_changeProperties(text=html_quote(request.txa_text))
431            for x in request.form.keys():
432                if x[0:4] == 'tat_':
433                    attrN = x[4:]
434                    attrV = request[x]
435                    e.saveAttribute(attrN,attrV)
436        elif (action == 'MOVE_UP'):
437            e = self.restrictedTraverse(p_path + p_id)
438            e.move_up()
439        elif (action == 'MOVE_DOWN'):
440            e = self.restrictedTraverse(p_path + p_id)
441            e.move_down()
442        elif (action in ['CUT','COPY']):
443            e = self.restrictedTraverse(p_path + p_id)
444            e.add_to_clipboard(action,request)
445        elif (action == 'PASTE'):
446            e = self.restrictedTraverse(p_path)
447            e.addChildFromClipboard(int(p_pos),obj=e)
448        if (action == 'EDIT'):
449            id_edit = p_id
450        else:
451            id_edit = ''
452
453        chd = self.possibleChild(obj=self)
454
455        #
456        #if not request.AUTHENTICATED_USER.has_permission('EditStructuredDocument',context):
457        #    return context.renderHTML()
458        #
459
460        response.setHeader('Content-type', 'text/xml')
461
462        printed+= '<?xml version="1.0" encoding="ISO-8859-1"?>\n'  #aqui tbm encoding poderia ser parametrizado
463        if xslt:
464            tpt = self.template()
465            if (xslt!="__default__"):
466                printed+= '<?xml-stylesheet type="text/xsl" href="%s"?>\n' % xslt
467            elif (tpt.default_xslt_for_editor):
468                printed+= '<?xml-stylesheet type="text/xsl" href="%s"?>\n' % tpt.default_xslt_for_editor
469        printed+= '<strdoc id="%s" type="%s">\n' % (self.id, self.type)
470        for c in chd:
471            if c[1] == 0:
472                if c[3]:
473                    str_opt = "yes"
474                else:
475                    str_opt = "no"
476                printed+= '    <sde_child type="%s" name="%s" pos="%s" opt="%s" path=""></sde_child>\n' % (c[0], c[2], c[1], str_opt)
477        pos = 0
478        for x in (self.objectValues()):
479            printed+= x.renderXMLforEditing(indent=1, id_edit=id_edit)
480            pos = pos + 1
481            for c in chd:
482                if c[1] == pos:
483                    if c[3]:
484                        str_opt = "yes"
485                    else:
486                        str_opt = "no"
487                    printed+= '    <sde_child type="%s" name="%s" pos="%s" opt="%s" path=""></sde_child>\n' % (c[0], c[2], c[1], str_opt)
488        for c in chd:
489            if c[1] > pos:
490                if c[3]:
491                    str_opt = "yes"
492                else:
493                    str_opt = "no"
494                printed+= '    <sde_child type="%s" name="%s" pos="%s" opt="%s" path=""></sde_child>\n' % (c[0], c[2], c[1], str_opt)
495        printed+= '</strdoc>\n'
496        response.setHeader('Content-type', 'text/xml')
497        return printed
498
499    # *** template
500    def template (self):
501        return self.restrictedTraverse(self.template_path + "/" + self.type)
Note: Veja TracBrowser para ajuda no uso do navegador do trac.
 

The contents and data of this website are published under license:
Creative Commons 4.0 Brasil - Atribuir Fonte - Compartilhar Igual.