code: public void addMixin(String mixinName) throws NoSuchNodeTypeException, ConstraintViolationException,
        VersionException, LockException, RepositoryException
     {
        checkValid();
  
        if (LOG.isDebugEnabled())
        {
           LOG.debug("Node.addMixin " + mixinName + " " + getPath());
        }
  
        InternalQName name = locationFactory.parseJCRName(mixinName).getInternalName();
  
        // Does the node already has the mixin
        for (InternalQName mixin : nodeData().getMixinTypeNames())
        {
           if (name.equals(mixin))
           {
              // we already have this mixin type
              if (LOG.isDebugEnabled())
              {
                 LOG.warn("Node already of mixin type " + mixinName + " " + getPath());
              }
              return;
           }
        }
  
        NodeTypeData type = session.getWorkspace().getNodeTypesHolder().getNodeType(name);
  
        // Mixin or not
        if (type == null || !type.isMixin())
        {
           throw new NoSuchNodeTypeException("Nodetype " + mixinName + " not found or not mixin type.");
        }
  
        if (definition.isProtected())
        {
           throw new ConstraintViolationException("Can not add mixin type. Node is protected " + getPath());
        }
  
        if (!isNew() && name.equals(Constants.EXO_OWNEABLE))
        {
           checkPermission(PermissionType.CHANGE_PERMISSION);
        }
  
        // Check if versionable ancestor is not checked-in
        if (!checkedOut())
        {
           throw new VersionException("Node " + getPath() + " or its nearest ancestor is checked-in");
        }
  
        // Check locking
        if (!checkLocking())
        {
           throw new LockException("Node " + getPath() + " is locked ");
        }
  
        doAddMixin(type);
     }
docs: {@inheritDoc}