예제 #1
0
bool UmlAttribute::new_one(Class * container, Q3CString name,
			   aVisibility visibility, bool constp,
			   bool staticp, const Q3CString & value,
			   Q3CString comment, Q3CString description)
{
#ifdef TRACE
  cout << "ATTRIBUTE '" << name << "'\n";
#endif
  
#ifndef REVERSE
  if (visibility == PrivateVisibility)
    return TRUE;
#endif
  
  if (((const char *) name)[0] == '$')
    name = name.mid(1);
  
  UmlClass * cl = container->get_uml();
  UmlAttribute * at = UmlBaseAttribute::create(cl, name);
  
  if (at == 0) {
    PhpCatWindow::trace(Q3CString("<font face=helvetica><b>cannot add attribute <i>")
			 + name + "</i> in <i>" + cl->name() 
			 + "</i></b></font><br>");  
    return FALSE;
  }
#ifdef REVERSE
  Statistic::one_attribute_more();
#endif
  
  if (!comment.isEmpty()) {
    Q3CString s = (at->phpDecl().find("${description}") != -1)
      ? description : comment;
    UmlTypeSpec t;
    int index;
    
    if (! (t.explicit_type = value_of(s, "@var", index)).isEmpty()) {
      at->set_Type(t);
      s.replace(index, t.explicit_type.length(), "${type}");
    }
    
    at->set_Description(s);
    
  }
  
  if (constp)
    at->set_isReadOnly(TRUE);
  
  if (staticp)
    at->set_isClassMember(TRUE);
  
  if (! value.isEmpty())
    at->set_DefaultValue(value);
  
  at->set_Visibility(visibility);
  
  return TRUE;
}
예제 #2
0
bool UmlAttribute::new_one(Class * container, const WrapperStr & name,
                           UmlTypeSpec typespec, aVisibility visibility,
                           bool staticp, bool finalp, bool transientp,
                           bool volatilep, const WrapperStr & array,
                           const WrapperStr & value, WrapperStr comment,
                           WrapperStr description, WrapperStr annotation
#ifdef ROUNDTRIP
                           , bool roundtrip, QList<UmlItem *> & expected_order
#endif
                          )
{
#ifdef TRACE
    QLOG_INFO() << "ATTRIBUTE '" << name << "'\n";
#endif

    if (
#ifdef REVERSE
        container->from_libp() && (
#endif
                                   visibility == PrivateVisibility
#ifdef REVERSE
                                   )
#endif
        )
    {
        Lex::finish_line();
        Lex::clear_comments();
        return TRUE;
    }

    UmlClass * cl = container->get_uml();
    UmlAttribute * at;

#ifdef ROUNDTRIP
    bool created;

    if (!roundtrip ||
        ((at = search_attr(container, name)) == 0)) {
#endif
        at = UmlBaseAttribute::create(cl, name);

        if (at == 0) {
            JavaCatWindow::trace(WrapperStr("<font face=helvetica><b>cannot add attribute <i>")
                                 + name + "</i> in <i>" + cl->name()
                                 + "</i></b></font><br>");
            return FALSE;
        }

#ifdef REVERSE
# ifndef ROUNDTRIP
        Statistic::one_attribute_more();
# else

        if (roundtrip)
            container->set_updated();

        created = TRUE;
    }
    else
        created = FALSE;

# endif
#endif

        Lex::finish_line();

        comment = Lex::get_comments(comment);
        description = Lex::get_description(description);

        WrapperStr decl = JavaSettings::attributeDecl("");
        int index = decl.find("${type}");

        if ((index == -1) || (decl.find("${name}") == -1)) {
            decl = "  ${comment}${@}${visibility}${static}${final}${transient}${volatile}${type} ${name}${value};";
            index = decl.find("${type}");
        }

#ifdef ROUNDTRIP

        if (roundtrip && !created) {
            if (decl.find("${description}") != -1) {
                if (nequal(at->description(), description)) {
                    at->set_Description(description);
                    container->set_updated();
                }
            }
            else if (nequal(at->description(), Lex::simplify_comment(comment))) {
                at->set_Description(comment); // comment was set
                container->set_updated();
            }

            if (at->isReadOnly() != finalp) {
                at->set_isReadOnly(finalp);
                container->set_updated();
            }

            if (at->isJavaTransient() != transientp) {
                at->set_isJavaTransient(transientp);
                container->set_updated();
            }

            if (at->isVolatile() != volatilep) {
                at->set_isVolatile(volatilep);
                container->set_updated();
            }

            if (at->isClassMember() != staticp) {
                at->set_isClassMember(staticp);
                container->set_updated();
            }

            if (!array.isEmpty())
                decl.insert(index + 7, "${multiplicity}");

            if (neq(at->multiplicity(), array)) {
                at->set_Multiplicity(array);
                container->set_updated();
            }

            WrapperStr v = at->defaultValue();

            if (!v.isEmpty() && (((const char *) v)[0] == '='))
                v = v.mid(1);

            if (nequal(v, value)) {
                at->set_DefaultValue(value);
                container->set_updated();
            }

            if (nequal(at->javaAnnotations(), annotation)) {
                at->set_JavaAnnotations(annotation);
                container->set_updated();
            }

            WrapperStr stereotype;
            bool force_ste = FALSE;

            if (cl->stereotype() == "enum") {
                stereotype = "attribute";
                force_ste = TRUE;
            }
            else if (typespec.type == 0) {
                WrapperStr t = typespec.explicit_type;
                int index2;

                if (!t.isEmpty() &&
                    (t.at(t.length() - 1) == ">") &&
                    ((index2 = t.find('<')) > 0)) {
                    stereotype = t.left(index2);
                    typespec.explicit_type =
                        // may be a,b ...
                        t.mid(index2 + 1, t.length() - 2 - index2);
                    decl.replace(index, 7, "${stereotype}<${type}>");
                    force_ste = TRUE;
                }
            }

            if (at->visibility() != visibility) {
                at->set_Visibility(visibility);
                container->set_updated();
            }

            if (neq(at->stereotype(), stereotype)) {
                WrapperStr jst;

                if (! at->stereotype().isEmpty())
                    jst = JavaSettings::relationAttributeStereotype(at->stereotype());

                if ((force_ste) ? (jst != stereotype) : (jst == "attribute")) {
                    at->set_Stereotype(stereotype);
                    container->set_updated();
                }
            }

            if (neq(at->javaDecl(), decl)) {
                at->set_JavaDecl(decl);
                container->set_updated();
            }

            if (!at->type().equal(typespec)) {
                at->set_Type(typespec);
                container->set_updated();
            }

            at->set_usefull();

            expected_order.append(at);
        }
        else {
#endif

            if (!comment.isEmpty())
                at->set_Description((decl.find("${description}") != -1)
                                    ? description : Lex::simplify_comment(comment));

            if (finalp)
                at->set_isReadOnly(TRUE);

            if (transientp)
                at->set_isJavaTransient(TRUE);

            if (volatilep)
                at->set_isVolatile(TRUE);

            if (staticp)
                at->set_isClassMember(TRUE);

            if (!array.isEmpty()) {
                decl.insert(index + 7, "${multiplicity}");
                at->set_Multiplicity(array);
            }

            if (! value.isEmpty())
                at->set_DefaultValue(value);

            if (! annotation.isEmpty())
                at->set_JavaAnnotations(annotation);

            if ((typespec.type == 0) && (cl->stereotype() != "enum")) {
                WrapperStr t = typespec.explicit_type;
                int index2 = 0;

                if (!t.isEmpty() &&
                        (t.at(t.length() - 1) == ">") &&
                    ((index2 = t.find('<')) > 0))
                {
                    at->set_Stereotype(t.left(index2));
                    typespec.explicit_type =
                        // may be a,b ...
                        t.mid(index2 + 1, t.length() - 2 - index2);
                    decl.replace(index, 7, "${stereotype}<${type}>");
                }
            }

            at->set_Visibility(visibility);

            if (cl->stereotype() == "enum") {
                at->set_JavaDecl(decl);
                at->set_Stereotype("attribute");
            }
            else if (decl != JavaSettings::attributeDecl(""))
                at->set_JavaDecl(decl);

            at->set_Type(typespec);

#ifdef ROUNDTRIP

            if (roundtrip)
                expected_order.append(at);
        }

#endif

        return TRUE;
    }
예제 #3
0
bool UmlAttribute::new_one(Class * container, const Q3CString & name,
			   const Q3CString & type, const Q3CString & modifier,
			   const Q3CString & pretype, const Q3CString & array,
			   aVisibility visibility, bool staticp, bool constp,
			   bool typenamep, bool mutablep, bool volatilep,
			   const Q3CString & bitfield, const Q3CString & value,
			   Q3CString comment, Q3CString description
#ifdef ROUNDTRIP
			   , bool roundtrip, Q3PtrList<UmlItem> & expected_order
#endif
			   )
{
#ifdef DEBUG_BOUML
  cout << "ATTRIBUTE '" << name << "' type '" << type << "' modifier '" << modifier << "' array '" << array << "'\n";
#endif
  
  if (
#ifdef REVERSE
      container->from_libp() &&
#endif
      (visibility == PrivateVisibility)) {
    Lex::finish_line();
    Lex::clear_comments();
    return TRUE;
  }
  
  UmlClass * cl = container->get_uml();
  UmlAttribute * at;
  
#ifdef ROUNDTRIP
  bool created;
  
  if (!roundtrip ||
      ((at = search_attr(cl, name)) == 0)) {
#endif
    at = UmlBaseAttribute::create(cl, name);
    
    if (at == 0) {
      UmlCom::trace(Q3CString("<font face=helvetica><b>cannot add attribute <i>")
		    + name + "</i> in <i>" + Q3CString(cl->name())
		    + "</i></b></font><br><hr>");  
      return FALSE;
    }
  
#ifdef REVERSE
# ifndef ROUNDTRIP
    Statistic::one_attribute_more();
# else
    if (roundtrip)
      container->set_updated();
    created = TRUE;
  }
  else
    created = FALSE;
# endif
#endif
  
  Lex::finish_line();
  
  comment = Lex::get_comments(comment);
  description = Lex::get_description(description);
  
  bool pfunc = (type.find('$') != -1);
  UmlTypeSpec typespec;
  Q3CString typeform;
  Q3CString stereotype;
  
  if (! pfunc) {
    typeform = (pretype.isEmpty())
      ? Q3CString("${type}")
      : pretype + " ${type}";
    
    container->compute_type(type, typespec, typeform);
  }
  else {
    typespec.explicit_type = type.simplifyWhiteSpace();
    
    int index = typespec.explicit_type.find("${name}");
    
    if (index != -1)
      typespec.explicit_type.remove(index, 7);
  }
  
  Q3CString decl = CppSettings::attributeDecl("");
  int index = decl.find("${type}");
  
  if ((index == -1) ||
      (decl.find("${const}") == -1) ||
      (decl.find("${name}") == -1) ||
      (decl.find("${mutable}") == -1) ||
      (decl.find("${volatile}") == -1) ||
      (decl.find(';') == -1)) {
    decl = "    ${comment}${static}${mutable}${volatile}${const}${type} ${name}${value};";
    index = decl.find("${type}");
  }
  
  if (pfunc)
    decl.replace(index, decl.find("${name}") + 7 - index, type);
  else {
    if (!modifier.isEmpty())
      decl.insert(index + 7, (const char*)(Q3CString(" ") + modifier));
        
    if (typeform != "${type}")
      decl.replace(index, 7, typeform);
    else if (typespec.type == 0) {
      Q3CString t = typespec.explicit_type;
      int index2;
      
      if (!t.isEmpty() &&
	  (t.at(t.length() - 1) == '>') &&
	  ((index2 = t.find('<')) > 0)) {
	stereotype = t.left(index2);
	typespec.explicit_type =
	  // may be a,b ...
	  t.mid(index2 + 1, t.length() - 2 - index2);
	decl.replace(index, 7, "${stereotype}<${type}>");
      }
    }
    
    if (!array.isEmpty())
      decl.insert(decl.find("${name}") + 7, "${multiplicity}");
    
    if (!bitfield.isEmpty())
      decl.insert(decl.find(';'), (const char *)(Q3CString(" : ") + bitfield));
  }
  
  if (typenamep) {
    int index = decl.find("${const}") + 8; // find cannot return -1
    int index2 = decl.find("${mutable}") + 10; // find cannot return -1
    int index3 = decl.find("${volatile}") + 11; // find cannot return -1
    
    if (index2 > index) index = index2;
    if (index3 > index) index = index3;
    
    decl.insert(index, "typename ");
  }
  
  if (!value.isEmpty() && ((index = decl.find("${value}")) != -1))
    decl.insert(index + 2,  "h_");
  
#ifdef ROUNDTRIP
  if (roundtrip && !created) {
    if (decl.find("${description}") != -1) {
      if (nequal(at->description(), description)) {
	at->set_Description(description);
	container->set_updated();
      }
    }
    else if (nequal(at->description(), Lex::simplify_comment(comment))) {
      at->set_Description(comment); // comment was set
      container->set_updated();
    }
          
    if (at->isReadOnly() != constp) {
      at->set_isReadOnly(constp);
      container->set_updated();
    }
    
    if (at->isCppMutable() != mutablep) {
      at->set_isCppMutable(mutablep);
      container->set_updated();
    }
    
    if (at->isVolatile() != volatilep) {
      at->set_isVolatile(volatilep);
      container->set_updated();
    }
    
    if (at->isClassMember() != staticp) {
      at->set_isClassMember(staticp);
      container->set_updated();
    }
    
    if (neq(at->multiplicity(), array)) {
      at->set_Multiplicity(array);
      container->set_updated();
    }
    
    if (!staticp) {
      Q3CString v = at->defaultValue();
      
      if (!v.isEmpty() && (((const char *) v)[0] == '='))
	v = v.mid(1);
      
      if (nequal(v, value)) {
	at->set_DefaultValue(value);
	container->set_updated();
      }
    }
    
    if (at->visibility() != visibility) {
      at->set_Visibility(visibility);
      container->set_updated();
    }
    
    if (!stereotype.isEmpty()) {
      Q3CString cppst;
      
      if (!at->stereotype().isEmpty())
	cppst = CppSettings::relationAttributeStereotype(at->stereotype());
      
      if (cppst != stereotype) {
	at->set_Stereotype(stereotype);
	container->set_updated();
      }
    }
    
    if (!at->type().equal(typespec)) {
      at->set_Type(typespec);
      container->set_updated();
    }
    
    if (neq(at->cppDecl(), decl)) {
      at->set_CppDecl(decl);
      container->set_updated();
    }
          
    at->set_usefull();
    
    expected_order.append(at);
  }
  else {
#endif
    if (!comment.isEmpty())
      at->set_Description((decl.find("${description}") != -1)
			  ? description : Lex::simplify_comment(comment));
    
    if (constp)
      at->set_isReadOnly(TRUE);
    
    if (mutablep)
      at->set_isCppMutable(TRUE);
    
    if (volatilep)
      at->set_isVolatile(TRUE);
    
    if (staticp)
      at->set_isClassMember(TRUE);
    
    if (!array.isEmpty())
      at->set_Multiplicity(array);
    
    if (! value.isEmpty())
      at->set_DefaultValue(value);
    
    at->set_Visibility(visibility);
    
    if (! stereotype.isEmpty())
      at->set_Stereotype(stereotype);
    
    at->set_Type(typespec);
    
    at->set_CppDecl(decl);
    
#ifdef ROUNDTRIP
    if (roundtrip)
      expected_order.append(at);
  }
#endif
  
  return TRUE;
}
예제 #4
0
void UmlAttribute::importIt(FileIn & in, Token & token, UmlItem * where)
{
  if (!token.valueOf("association").isNull())
    UmlRelation::importAsAttribute(in, token, where);
  else {
    where = where->container(anAttribute, token, in);
    
    if (where != 0) {
      QCString s = token.valueOf("name");
      
      if (s.isEmpty()) {
	static unsigned n = 0;
	
	s.sprintf("anonymous_attribute_%u", ++n);
      }
      else
        s = legalName(s);
      
      UmlAttribute * att = create((UmlClass *) where, s);
      
      if (att == 0)
	in.error("cannot create attribute '" + s +
		 "' in '" + where->name() + "'");
      
      att->addItem(token.xmiId(), in);
      
      if (token.what() == "ownedliteral")
	att->set_Visibility(PublicVisibility);
      else
	att->setVisibility(token.valueOf("visibility"));
      
      if (token.valueOf("isreadonly") == "true")
	 att->set_isReadOnly(TRUE);
      
      if (token.valueOf("isderived") == "true")
	 att->set_isDerived(TRUE, (token.valueOf("isderivedunion") == "true"));
      
      if (token.valueOf("isordered") == "true")
	 att->set_isOrdered(TRUE);
      
      if (token.valueOf("isunique") == "true")
	 att->set_isUnique(TRUE);
      
      if (!(s = token.valueOf("type")).isEmpty()) {
	UmlTypeSpec ts;
	
	if (att->setType(s, ts))
	  att->set_Type(ts);
      }
      
      if (!(s = token.valueOf("defaultvalue")).isEmpty())
	att->set_DefaultValue(s);
      
      if (token.valueOf("isstatic") == "true")
	att->set_isClassMember(TRUE);
	  
      if (! token.closed()) {
	QCString k = token.what();
	const char * kstr = k;
	
	while (in.read(), !token.close(kstr)) {
	  s = token.what();
	  
	  if (s == "type") {
	    UmlTypeSpec ts;
	    
	    if (att->setType(token, ts))
	      att->set_Type(ts);
	    if (! token.closed())
	      in.finish(s);
	  }
	  else if (s == "defaultvalue") {
	    att->set_DefaultValue(token.valueOf("value"));
	    if (! token.closed())
	      in.finish(s);
	  }
	  else if (s == "lowervalue")
	    att->importMultiplicity(in, token, FALSE);
	  else if (s == "uppervalue")
	    att->importMultiplicity(in, token, TRUE);
	  else if (s == "upperbound") {
	    if (! token.closed())
	      in.finish(s);
	  }
	  else if ((s == "specification") && (k == "ownedliteral")) {
	    if (! token.closed())
	      in.finish(s);
	  }
	  else if (s == "ownedrule")
	    att->set_Constraint(UmlItem::readConstraint(in, token));
	  else
	    att->UmlItem::import(in, token);
	}
      }
    }
  }
}